Skip to content

موضوع البحث: G:\GitHub\OpenTTD-patches (مساحة عمل كود مصدر jgrpp) الموارد المرجعية: G:\game\openttd-jgrpp (لعبة كاملة مجمعة، للقراءة فقط) تاريخ البحث: 2026-08-14 الفرع: jgrpp (HEAD الحالي 5b5c452e1b، حوالي إصدار 16.0)


1. نظرة عامة على المشروع ​

OpenTTD jgrpp (JGR's Patchpack) هو فرع محسّن معروف يعتمد على OpenTTD، كود المصدر في مساحة العمل هذه يقابل الإصدار 16.0، يحتوي على عدد كبير من الميزات الخاصة بـ JGR (tracerestrict، إشارات قابلة للبرمجة، جدولة مجدولة، استبدال القوالب، إشارات محسّنة، إلخ).

المشروعالوصف
اللغةC++20 (CMAKE_CXX_STANDARD 20، بدون امتدادات)
البناءCMake (≥3.17)، src/CMakeLists.txt منظم حسب الدليل
محرك البرامج النصيةSquirrel (src/3rdparty/squirrel/)، يُستخدم لـ AI / GameScript / البرامج النصية للقوالب
الشبكةطبقة بروتوكول TCP/UDP مخصصة (src/network/)، HTTP يستخدم WinHttp (Windows) / libcurl (أخرى) / JS (Emscripten)
الحفظتنسيق ثنائي مخصص src/saveload/ + src/sl/
الخيوطsrc/thread.h + src/worker_thread.cpp (تجمع مهام WorkerThreadPool)، src/timer/ مؤقتات

2. هيكل دليل المصدر وتقسيم الوحدات ​

المستوى العلوي: CMakeLists.txt هو سكريبت البناء الجذر؛ src/ هو كود C++ بالكامل؛ bin/ هو بيانات وقت التشغيل (سكريبتات AI المتوافقة، ملفات اللغة، إلخ)؛ media/، os/، cmake/، docs/ تحتوي على الموارد وكود المنصة وسكريبتات البناء والوثائق على التوالي.

الأدلة الفرعية الرئيسية داخل src/ ومسؤولياتها:

الدليلالمسؤولية
src/core/أدوات أساسية: أنواع pool، bitset، حاويات، تغليف الخيوط، عمليات البت، إلخ
src/network/الشبكات: خادم/عميل/UDP/HTTP/تنزيل المحتوى/بروتوكول الإدارة (core/ دليل فرعي لأساسيات البروتوكول)
src/script/إطار تشغيل البرامج النصية: تغليف Squirrel، مثيلات، تكوين؛ api/ هو جميع فئات API المعرّضة لـ AI/GS
src/ai/إطار NoAI (مثيلات AI، ماسح ضوئي، تكوين، واجهة مستخدم رسومية)
src/game/إطار GameScript (مثيلات GS، تكوين، واجهة مستخدم رسومية)
src/newgrf/فك تشفير ومعالجة NewGRF
src/pathfinder/التوجيه (YAPF، NPF)
src/saveload/، src/sl/قراءة وكتابة الحفظ
src/blitter/، src/video/، src/fontcache/، src/music/، src/sound/الواجهات الخلفية للعرض/الصوت والفيديو
src/lang/مصادر سلاسل الترجمة (يتم توليدها بواسطة strgen)
src/table/جداول ثابتة؛ table/settings/*.ini هو مصدر تعريف الإعدادات (يتم توليدها بواسطة settingsgen)
src/3rdparty/مكتبات طرف ثالث (squirrel، llvm، icu، إلخ)
src/timer/، src/os/، src/misc/مؤقتات، منصة، متنوعات

الملفات المنتشرة في المستوى العلوي مسماة حسب النظام (مثل rail_gui.cpp، group_cmd.cpp، vehicle.cpp، order_cmd.cpp، economy.cpp)، تتبع اصطلاح OpenTTD: *_cmd لمنطق الأوامر، *_gui للنوافذ، *_base/_type/_func لهياكل البيانات والدوال المضمنة.


3. طريقة البناء ​

  • ثلاث خطوات CMake: cmake -B build .. ← cmake --build build ← الناتج openttd.exe. المستودع يأتي مع build.sh / build-dedicated.sh.
  • التبعيات: معلنة في vcpkg.json (zlib، lzma، lzo، zstd، png، SDL2، freetype، harfbuzz، icu، opus، إلخ)؛ Windows يستخدم WinHttp (لا حاجة لـ curl)، غير Windows يستخدم libcurl (CMakeLists.txt:121-127).
  • سلسلة أدوات (أدوات المضيف): strgen (ملفات اللغة)، settingsgen (توليد كود الإعدادات من src/table/settings/*.ini)، squirrel_export (توليد ربط Squirrel من src/script/api/script_*.hpp).
  • المخرجات الرئيسية: generated/script/api/<ai|gs>/...sq.hpp (ربط API، يتم اكتشافه تلقائياً بواسطة file(GLOB script_*.hpp)، إضافة فئات API جديدة لا يتطلب تعديل قائمة التسجيل، فقط أضف .hpp وأضف .cpp إلى قائمة مصادر src/script/api/CMakeLists.txt)؛ generated/rev.cpp؛ generated/ottdres.rc.
  • نظام الإعدادات: الإصدار الحديث تم تغييره إلى محرك INI——src/table/settings/*.ini (تحتوي على أقسام [SDTC_VAR]، cat=SC_* تصنيف، flags، post_cb، إلخ)، يتم توليد settings_*.cpp/h بواسطة settingsgen؛ أعضاء الهيكل المقابلون في src/settings_type.h (مثل NetworkSettings يبدأ من سطر 575).

4. مواقع تنفيذ أنظمة الوظائف الخمس الرئيسية ​

4.1 تنزيل الموارد (تنزيل المحتوى / BaNaNaSplit) ​

نقطة الاهتمامالموقع
الفئة الرئيسية لعميل المحتوىsrc/network/network_content.h/.cpp — ClientNetworkContentSocketHandler (أيضاً ContentCallback + HTTPCallback)
واجهة مستخدم تنزيل المحتوىsrc/network/network_content_gui.cpp/.h
عميل HTTPsrc/network/core/http.h/.cpp — NetworkHTTPSocketHandler::Connect(uri, callback, data)، غير متزامن يعتمد على الأحداث (غير معطل، استقصاء الحلقة الرئيسية)
سلسلة اتصال خادم المحتوىsrc/network/core/config.cpp — NetworkContentServerConnectionString(): متغير البيئة OTTD_CONTENT_SERVER_CS، الافتراضي content.openttd.org (بروتوكول بيانات وصفية TCP)
URI المرآةsrc/network/core/config.cpp — NetworkContentMirrorUriString(): متغير البيئة OTTD_CONTENT_MIRROR_URI، الافتراضي https://binaries.openttd.org/bananas
تدفق التنزيلDownloadSelectedContent() ← DownloadSelectedContentHTTP() (POST لجميع معرفات المحتوى إلى المرآة، تعيد المرآة تدفق tar متعدد الملفات، كتابة ملف تلو الآخر) ← AfterDownload() يقوم بـ gunzip + TarScanner فك الضغط
فك الضغطGunzipFile() (zlib)، TarScanner/ExtractTar (src/tar_type.h / src/fileio.cpp)
تسهيلات الخيوط (يمكن استخدامها للتوازي)src/worker_thread.h/.cpp — WorkerThreadPool + EnqueueJob؛ src/thread.h هو تغليف خيوط المنصة

استنتاج الوضع الحالي: ① يوجد مرآة واحدة فقط ويمكن تكوينها فقط عبر متغيرات البيئة، لا يوجد إعداد داخل اللعبة؛ ② التنزيل هو اتصال واحد، تسلسلي (POST واحد لجميع الملفات)؛ ③ فك الضغط يتم تنفيذه بشكل متزامن في الخيط الرئيسي. ← نقاط تحسين متعددة الخيوط/متعددة المرايا واضحة.

4.2 الحد الأقصى للاعبين عبر الإنترنت / الشركات في الخادم ​

نقطة الاهتمامالموقع
ثابت حد العميلsrc/network/network_type.h:21 — static const uint MAX_CLIENTS = 255;
تجمع العميلنفس الملف ClientPoolIDTag : PoolIDTraits<uint16_t, MAX_CLIENTS + 1, 0xFFFF>؛ ClientID هو uint32_t
تجمع معرف الشركةsrc/company_type.h — CompanyIDTag : PoolIDTraits<uint8_t, 0xF, 0xFF> → MAX_COMPANIES = CompanyID::End().base() = 15؛ الشركات الوهمية تشغل 253/254/255
قناع الشركةنفس الملف CompanyMask : BaseBitSet<CompanyMask, CompanyID, uint16_t> (16 بت، يمكنه تتبع 16 شركة فقط)
التحقق من قبول الخادمsrc/network/network_server.cpp:360 — _network_clients_connected < MAX_CLIENTS؛ static_assert(NetworkClientSocketPool::MAX_SIZE == MAX_CLIENTS + 1)
عناصر إعداد العميلsrc/table/settings/network_settings.ini:231/241 — network.max_companies (def 15, max MAX_COMPANIES)، network.max_clients (def 25, max MAX_CLIENTS)؛ الهيكل في src/settings_type.h NetworkSettings
عرض بت البروتوكول (قيد صارم)src/network/core/network_game_info.cpp — يتم إرسال companies_max و clients_max عبر Send_uint8/Recv_uint8 (السطور 251-296، 422-432)
عرض قائمة الخادمsrc/network/network_gui.cpp:519، إلخ

استنتاج الوضع الحالي:

  • حد العميل = 255 هو بالفعل حد البروتوكول (حقل uint8 + توافق منسق اللعبة/متصفح الخادم). لتجاوزه، يجب تغيير الحقول ذات الصلة في network_game_info إلى uint16 (رابط client↔server بالكامل + بث UDP + بروتوكول منسق اللعبة)، وهو تغيير في البروتوكول الخارجي.
  • حد الشركة = 15 (CompanyIDTag End=0xF). يمكن رفعه بأمان إلى 252 (End=0xFC): القاعدة لا تزال uint8، عرض بايت الحفظ لم يتغير (متوافق مع الحفظ القديم)، يحتاج إلى توسيع CompanyMask (uint16→uint32) وافتراضات الواجهة/الحلقة.

4.3 تجميع المركبات ​

نقطة الاهتمامالموقع
هيكل بيانات التجميعsrc/group.h — Group : GroupPool::PoolItem (name/owner/vehicle_type/flags/livery/statistics/parent/number)؛ GroupID، DEFAULT_GROUP، IsDefaultGroupID/IsAllGroupID/IsTopLevelGroupID
أوامر التجميعsrc/group_cmd.cpp — CmdCreateGroup(536)، CmdDeleteGroup(585)، CmdAlterGroup(646)، CmdAddVehicleGroup، CmdAddSharedVehicleGroup (إضافة مركبات الطلبات المشتركة إلى مجموعة موجودة، بالقرب من سطر 718 AddVehicleToGroup)
تسجيل الأوامرsrc/group_cmd.h:27-35 — DEF_CMD_TUPLE_NT(Commands::XXX, CmdXXX, {}, CommandType::RouteManagement, CmdDataT<...>)؛ التعداد في src/command_type.h enum class Commands (من سطر 492)
واجهة مستخدم التجميعsrc/group_gui.cpp/.h، src/vehiclelist.cpp
مركبة↔مجموعةsrc/vehicle_base.h (Vehicle::group_id)، SetTrainGroupID/UpdateTrainGroupID (group.h:130-131)
الطلبات/الجدولة المشتركةsrc/order_base.h (OrderList، VehicleOrdersID)، src/order_cmd.cpp، src/order_func.h، src/schdispatch.h/.cpp (جدولة مجدولة، مرتبطة بقائمة الطلبات)
إحصائيات التجميعGroupStatistics (group.h:60-66)، GetGroupNumVehicle، إلخ (group.h:125-128)

استنتاج الوضع الحالي: يوجد بالفعل CmdAddSharedVehicleGroup (إضافة مركبات الطلبات المشتركة لمركبة إلى مجموعة ما) و CmdCreateGroupFromList (إنشاء مجموعة من قائمة)، لكن لا يوجد منطق كامل لـ "إنشاء المجموعات وتجميعها تلقائياً حسب الطلبات المشتركة". الأمر الجديد AutoGroupSharedOrders (اجتياز جميع المركبات الرئيسية للشركة ← تجميع حسب OrderList ← إنشاء مجموعة تلقائياً وتجميعها) مسار تنفيذه واضح.

4.4 تلميح البناء (تلميح سعر فوق الماوس عند بناء السكك، إلخ) ​

نقطة الاهتمامالموقع
واجهة مستخدم بناء السكك / منطقهاsrc/rail_gui.cpp (BuildRailToolbarWindow)، src/rail_cmd.cpp، src/rail.h/.cpp؛ الطريق road_gui.cpp/road_cmd.cpp
تقدير التكلفةDoCommand في كل *_cmd.cpp يرجع CommandCost؛ داخل واجهة المستخدم يمكن استخدام وضع DC_QUERY_COST للاستعلام عن السعر
البلاطة تحت الماوسsrc/viewport_func.h:36 — GetTileBelowCursor()؛ _cursor.pos (إحداثيات الشاشة)؛ src/viewport.cpp:1056
آلية تلميح النص الحاليةsrc/texteff.hpp — AddTextEffect(msg, x, y, duration, mode, ...) (نص عائم في إحداثيات العالم)، UpdateTextEffect؛ src/texteff.cpp
تجربة مستخدم تلميح البناء الحاليةشريط أدوات السكك عند OnPlaceDrag السحب تظهر المنطقة المحددة وتكلفة متراكمة (_thd tilehighlight، src/tilehighlight_func.h)؛ شريط الحالة statusbar_gui.cpp يمكنه عرض تكلفة الأداة
نقطة التحديث لكل إطارنوافذ شريط الأدوات المختلفة OnMouseLoop / viewport.cpp HandleMouseEvents (السطور 5422/5733)

استنتاج الوضع الحالي: لا يوجد "تلميح سعر فوق الماوس". يمكن استخدام AddTextEffect لتثبيته على بلاطة الماوس (يتبع مؤشر الماوس)، أو رسم تلميح بإحداثيات الشاشة بنفسك؛ يمكن استخدام DC_QUERY_COST للأداة الحالية للاستعلام عن سعر بلاطة واحدة + تراكم منطقة التحديد المسحوبة.

4.5 واجهة AI (الحفاظ على NoAI + ذكاء اصطناعي يدرك اللعبة بأكملها) ​

نقطة الاهتمامالموقع
إطار NoAIsrc/ai/ — ai_core.cpp (الحلقة الرئيسية AICore)، ai_instance.cpp (AIInstance/Squirrel VM)، ai_scanner.cpp (مسح دليل ai/)، ai_gui.cpp (اختيار/تكوين)، ai_config.cpp
إطار GameScriptsrc/game/ — game_core.cpp، game_instance.cpp، إلخ (GS هو "وضع إلهي"، صلاحياته أعلى من AI)
فئات API للبرامج النصيةsrc/script/api/script_*.hpp/.cpp (script_company، script_map، script_vehicle، script_industry، script_town، script_game، script_admin، إلخ، أكثر من 60 فئة)
تسجيل API التلقائيsrc/script/api/CMakeLists.txt — file(GLOB script_*.hpp) يولد تلقائياً روابط ai_*.sq.hpp/gs_*.sq.hpp؛ يجب إضافة .cpp إلى قائمة المصادر (من سطر 235)
ماكرو ربط Squirrelsrc/script/squirrel_class.hpp — DefSQClass / DefSQStaticMethod؛ ai/ai_controller.sq.hpp هو ربط وحدة التحكم AI
جدولة المثيلاتsrc/script/script_instance.cpp، src/script/script_suspend.hpp (تعليق/استئناف)، أحداث script_event*
التحكم في الوصول للشركةsrc/script/api/script_object.hpp:318 — ScriptObject::GetCompany()؛ ScriptCompanyMode (IsDeity()) يميز وضع GS الإلهي؛ التحقق من معامل API للشركة ResolveCompanyID، EnforceCompanyModeValid
إعدادات البرامج النصيةsrc/table/settings/script_settings.ini (game.script.*)؛ تكوين مثيل AI ai_config.cpp

استنتاج الوضع الحالي: في واجهة برمجة تطبيقات البرامج النصية الحديثة، بعض معلومات المنافسين (مثل GetBankBalance) لم تعد مقيدة، لكن لا توجد واجهة برمجة تطبيقات تجميعية موجهة للإدراك الكامل للعبة (لا توجد مدخلات موحدة لـ "تعداد جميع الشركات/الاقتصاد العام/إحصائيات الخريطة العامة")، ولا توجد نقطة وصول "AI عام" يتحكم فيها مفتاح. إضافة فئة API ScriptGlobal (تسجيل GLOB تلقائي) + إعداد game.script "السماح للإدراك العام للعبة" يمكن أن يحقق ذلك، GS متاح دائماً (وضع إلهي)، AI يتحكم فيه المفتاح——أي "الحفاظ على NoAI، إضافة ذكاء اصطناعي يدرك اللعبة بأكملها، مع تحكم في الوصول".


5. نظرة عامة على مخاطر التعديل ​

الوظيفةملفات التعديل الرئيسيةالمخاطر
F1 تنزيل متعدد المصادر/متعدد الخيوطsrc/table/settings/network_settings.ini، src/settings_type.h، src/network/core/config.cpp، src/network/network_content.h/.cppمتوسط (آلة حالة استدعاء الشبكة تحتاج إلى عناية)
F2 توسيع الحدودsrc/company_type.h، src/table/settings/network_settings.ini، src/network/core/network_game_info.cpp (uint16 اختياري)منخفض-متوسط (الشركة 252 منخفض المخاطر؛ عميل >255 يتطلب تغيير بروتوكول)
F3 تجميع المركبات تلقائياًsrc/group_cmd.h/.cpp، src/command_type.h، src/console_cmds.cpp، src/group_gui.cpp، src/lang/english.txtمنخفض
F4 تلميح البناءجديد src/construction_cost_tip.h/.cpp، src/rail_gui.cpp/road_gui.cpp خطافات، src/lang/english.txtمنخفض-متوسط
F5 ذكاء اصطناعي يدرك اللعبة بأكملهاجديد src/script/api/script_global.hpp/.cpp، src/script/api/CMakeLists.txt، src/table/settings/script_settings.ini، AI نموذجي bin/ai/GlobalAI/منخفض (تسجيل تلقائي للإطار)

ملاحظة: جميع التعديلات تستند إلى مساحة العمل المحلية لفرع jgrpp، لم يتم التحقق من التجميع (لا توجد سلسلة أدوات بناء متاحة على هذا الجهاز)؛ يمكن مراجعة جميع التصحيحات عبر git diff ثم git apply.

آخر تحديث: