# Castle Siege — Çatı Tasarım Spec'i (Architecture) - **Tarih:** 2026-07-14 - **Durum:** Onaylandı (kullanıcı) → uygulama planına geçiliyor - **Kapsam:** Bu bir **çatı (umbrella) spec**'idir. Tam CS tek plana sığmaz; iş fazlara (Faz 0 + P1–P5) bölünmüştür ve her faz kendi detaylı plan → uygulama döngüsünü alır. İlk plan **Faz 0 (bootstrap + fork kurulumu)** için yazılacaktır. --- ## 1. Amaç ve hedef MuMain S6 mobil client'ına bağlı OpenMU sunucusuna **tam fonksiyonel Castle Siege** eklemek; bunu, upstream OpenMU güncellemelerini almaya devam edebileceğimiz ve **kendi custom işlerimizi (remote-NPC + CS) bozmayan** bir fork/derleme/deploy akışıyla yapmak. Kritik bulgu: **client Castle Siege'i zaten biliyor.** MuMain S6 kaynağında `GMBattleCastle` (CS haritası), guild mark işleme, `WSclient.cpp` içinde CS paket handler'ları hazır. Bu yüzden CS bizim için **~%80 server-side (OpenMU C#) iş**tir. Client'ta zaten var olan davranışı doğru protokol paketleriyle tetiklemek kalıyor. ## 2. Gereksinimler ### CS ürün gereksinimleri 1. **Tam fonksiyonel CS** — tüm resmi mekanikler (kayıt, guild mark/Sign of Lord, kuşatma, taht contention, sahiplik, vergi, Guardian Statue). 2. **Kale sahibine özel av haritası** — kale içi hunting zone; yalnızca sahip guild üyeleri (ve alliance) girebilir; özel monster/drop. 3. **Ayarlanabilir döngüler** — kayıt/kuşatma süre ve zamanları config'ten (günlük/haftalık/dakikalık test dahil). 4. **Her şey admin kontrolünde** — AdminPanel + chat komutları: başlat/durdur, sahip guild'i zorla ata, config düzenle, durum gör, sıfırla. ### Deployment / entegrasyon gereksinimleri 5. **Kendi server image'i** — stock `munique/openmu` image + DLL enjeksiyonu bırakılacak; image kaynaktan (`src/Startup/Dockerfile`) derlenecek, custom kod (remote-NPC + CS) içinde olacak. 6. **Upstream takibi otomatik** — AdamuSw'e `upstream` remote'u; `git fetch upstream && git merge upstream/master` ile yeni feature'lar alınır. **Bu merge'ler NPC + CS işini bozmamalı.** 7. **DockerHub deploy** — image build → tag → DockerHub push → başka sunucuda ayağa kaldır. ## 3. Kapsam kararları (netleştirilmiş) | Konu | Karar | |---|---| | Fidelity | Tam resmi CS | | Zamanlama | Konfigüre edilebilir döngü (`Timetable` tabanlı) | | Admin | Tam admin kontrolü (AdminPanel + chat komutları) | | Client değişikliği | **İlke: minimum.** Server'ı client'ın beklediği mevcut S6 CS protokolüne uydur. | | Mimari | Yaklaşım B: ayrı `CastleSiege` alt-sistemi; guild + PeriodicTask + MiniGame parçalarını yeniden kullan | --- ## 4. Repo topolojisi ve rolleri | Konum | Rol | |---|---| | `d:/OpenMU/` (branch `main`) | Eski customized fork — remote-NPC değişikliklerinin kaynağı (`src/GameLogic/PlayerActions/TalkNpcAction.cs`, `GameMap.cs`, `TalkNpcHandlerPlugInBase.cs`). Dağınık (build artifact'ları commit'lenmiş). Sadece **diff kaynağı** olarak kullanılacak. | | `.../OpenMU/` (`origin=MUnique`, temiz) | Upstream referans — güncel OpenMU (baseline commit `b5a0961`). | | `.../AdamuSw/` (`origin=gitea.atfatmc.com/atfatmc/AdamuSw`, branch `main`, boş) | **Ürün repo** — CS + remote-NPC burada; image buradan derlenir. | Hedef git kurulumu: ``` AdamuSw/ origin = https://gitea.atfatmc.com/atfatmc/AdamuSw.git (ürün) upstream = https://github.com/MUnique/OpenMU.git (referans) ``` --- ## 5. Mimari CS, OpenMU içinde **kalıcı bir alt-sistem** olarak kurulur (yaklaşım B). Üç mevcut altyapı yeniden kullanılır: - **Guild sistemi** (`GuildServer` + `Guild.AllianceGuild` / `Guild.Hostility`) → kayıt, alliance, sahiplik. - **PeriodicTask deseni** (`PeriodicTaskConfiguration.Timetable` + `IsItTimeToStart()` + `PeriodicTaskBasePlugIn.ForceStart()`) → zamanlama + admin zorla-başlat. - **MiniGame parçaları** (`MiniGameContext`: spawn dalgası, terrain değişimi, `Destructible` NPC'ler, harita oluşturma) → kuşatma savaşı mekaniği. **Not:** `MiniGameContext`'i subclass ETMEYECEĞİZ (instance/kısa-ömür modeli CS'nin kalıcı-sahiplik doğasına uymaz); onun parçalarını doğrudan kullanacağız. Merkezde yeni `CastleSiegeContext`: uzun ömürlü, kalıcı harita üstünde çalışan, kendi faz state machine'ine sahip servis. Bir periyodik plugin (`CastleSiegeEventPlugIn`) timetable'a bakıp faz geçişini tetikler. ### Faz state machine ``` Ownership (sahiplik dönemi) │ timetable: kayıt açılış ▼ Registration ──► guild master NPC'de kayıt, guild mark, ücret, min guild şartları │ kayıt kapanış ▼ Preparation ──► savunmacı = mevcut sahip; Guardian Statue'lar kurulur │ timetable: kuşatma saati ▼ Siege ──► kapı kır → kristal/statü yık → taht switch'i tut (contention) │ kuşatma süresi doldu ▼ Settlement ──► en çok taht tutan guild = yeni sahip; DB'ye yaz ▼ Ownership (yeni sahip) ──► döngü başa ``` ## 6. Bileşenler ### 6.1 Persistence (yeni veri modeli) — restart'ı atlatması ŞART - `CastleSiegeState` (tekil/kalıcı): mevcut sahip guild, aktif faz, sonraki kayıt/kuşatma zamanı, vergi oranı, biriken vergi. - `CastleSiegeRegistration`: bu döngüdeki guild kayıtları (guild, zaman, guild mark sayısı/rank, alliance). - `CastleSiegeConfiguration : PeriodicTaskConfiguration`: kayıt/kuşatma pencereleri, min guild seviye/üye, kayıt ücreti, vergi alt/üst sınırı, harita/NPC/kapı/kristal/switch tanım referansları. > **Karar noktası (plan aşamasında):** OpenMU persistence, kaynak-üretilmiş EF modelleri kullanır (DataModel projesi). Yeni kalıcı entity eklemek DataModel + Initialization + EF migration'a dokunmayı gerektirir → **touch registry**'ye girer. ### 6.2 Zamanlama / yaşam döngüsü - `CastleSiegeEventPlugIn` — periyodik plugin; timetable'dan kayıt-açılış ve kuşatma zamanlarını okur, `CastleSiegeContext`'in fazını ilerletir. Admin `ForceStart` ile fazı zorlar. ### 6.3 Kuşatma savaşı (Siege fazı, kalıcı CS haritası; client: `GMBattleCastle`) - **Kapılar** — HP'li `Destructible`; kırılınca terrain açılır (MiniGame terrain-change). - **Kristaller / Guardian Statue'lar** — yıkılması gereken `Destructible`'lar. - **Taht switch'i** — ele geçirme noktası; guild switch'i kullanınca "occupier"; contention = tutma süresi / switch sayısı. - Siege sırasında PvP açık; yalnızca kayıtlı guild üyeleri haritaya girebilir. ### 6.4 Sahiplik settlement - Kuşatma sonunda kazanan (tahtı en çok/son tutan guild) belirlenir; `CastleSiegeState.OwnerGuild`'a yazılır, persist edilir; ödüller verilir. ### 6.5 Sahiplik ödülleri - **Vergi sistemi** — sahip guild Loren Market NPC'lerinde vergi % belirler; alışveriş/store para akışına hook, vergi payı guild havuzuna; sahip birikeni çeker. - **Sahibe özel av haritası (Gereksinim 2)** — kale içi hunting zone; giriş warp'ı `guild == owner` (ve alliance) kontrolü yapar; özel monster/drop. - **Guardian Statue'lar** — sahip, sonraki kuşatma için savunma statülerini güçlendirebilir. ### 6.6 Kayıt akışı (tam resmi) - Guild master → Guardsman NPC (kayıt penceresinde) → Guild Mark (Sign of Lord'dan craft / drop) → ücret + min guild şartları → attack rank. ### 6.7 Protokol katmanı - **İlke:** server'ı client'ın beklediği mevcut S6 CS protokolüne uydur; client'a dokunma. - Yeni `GameLogic/Views/CastleSiege/` view plugin arayüzleri + `Network/Packets` (ServerToClient) builder'ları + `GameServer/MessageHandler` (ClientToServer) handler'ları; `WSclient.cpp`'deki mevcut handler'lara eşle. ### 6.8 Admin kontrol (Gereksinim 4) - AdminPanel sayfası + chat komutları: kayıt/kuşatma zorla başlat-durdur, sahip guild'i zorla ata, config düzenle, kayıt/sahip/vergi görüntüle, CS sıfırla. --- ## 7. Entegrasyon & Deployment stratejisi ### 7.1 Faz 0 — Bootstrap (bir kerelik, CS'den önce) 1. Temiz upstream OpenMU kaynağını AdamuSw'e kopyala (upstream `.git` hariç); ilk commit: `baseline: OpenMU b5a0961`. 2. AdamuSw'e `upstream` remote'u ekle (MUnique/OpenMU). 3. Eski fork'tan (`d:/OpenMU/src`) remote-NPC değişikliklerini diff'leyip AdamuSw'e port et; `// ADAMU-CUSTOM` işaretle; touch-registry'ye ekle; commit + Gitea push. 4. Image'i `src/Startup/Dockerfile`'dan derle, lokal test → çalıştığını doğrula. 5. DockerHub'a tag + push; başka sunucuda ayağa kaldır. Stock image'i bırak. Bu adım memory'deki **"MissingMethod tuzağını" kökten çözer** (her şey tek kaynaktan birlikte derlenir). ### 7.2 Merge güvenliği — "upstream merge NPC+CS'yi bozmasın" 1. **Additive-first:** CS'nin ~%90'ı yeni dosya/plugin (yeni dosya = sıfır conflict). OpenMU `[PlugIn]` mimarisi bunu destekler. 2. **Core dokunuşlarını minimize + işaretle:** kaçınılmaz core edit'leri `// ADAMU-CUSTOM: ` blokları ile sar. 3. **Touch registry** (§9): dokunulan her core dosyası + neden + değişiklik; merge conflict'te kontrol haritası. 4. **Regresyon testleri:** remote-NPC ve CS için unit/entegrasyon testleri; her merge sonrası koşulur → bozulma varsa anında görünür. ### 7.3 Güncelleme akışı (tekrarlanan) ``` git fetch upstream git merge upstream/master # conflict → ADAMU-CUSTOM + touch registry ile çöz dotnet test # regresyon: NPC + CS yeşil mi? docker build -f src/Startup/Dockerfile -t /adamu-openmu: . docker push /adamu-openmu: # hedef sunucuda: docker pull + up ``` --- ## 8. Hata yönetimi - **Server restart** (herhangi bir faz) → `CastleSiegeState`'ten (faz + zaman damgaları + sahip + kayıtlar) yükle; timestamp'e göre doğru faza devam et. Sahiplik ve faz restart'ı atlatmalı. - **Kayıt yok** → kuşatma atlanır; mevcut sahip korur (walkover). - **Beraberlik** → mevcut sahip korur. - **Sahip guild dağılırsa** → kale sahipsiz (neutral). ## 9. Touch registry (core dokunuşları — canlı liste) > Faz 0 ve her fazda güncellenecek. Amaç: upstream merge'lerde çakışma riskini denetlenebilir tutmak. | Dosya | Faz | Neden | Durum | |---|---|---|---| | `GameLogic/PlayerActions/TalkNpcAction.cs` | 0b | remote-NPC: `TalkToNpcByNumberAsync` (additive metod) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli | | `GameLogic/GameMap.cs` | 0b | remote-NPC: `GetNpcByNumber` helper (additive metod) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli; test: `GameMapTest.GetNpcByNumberFindsSpawnedNpcAsync` | | `GameServer/MessageHandler/TalkNpcHandlerPlugInBase.cs` | 0b | remote-NPC: `0x8000` marker dalı (tek gerçek core-logic dokunuşu) | ✅ Uygulandı, `// ADAMU-CUSTOM` işaretli | | `GameLogic/Player.cs` | P3 | CS PvP: Siege fazında Valley of Loren'de (map 30) kill izni (`IsCastleSiegeBattleActive`) | ✅ Uygulandı, `// ADAMU-CUSTOM` | | `GameLogic/GameContext.cs` | P3 | `MapInitializer` property expose (guardian heykel Destructible runtime spawn) | ✅ Uygulandı, `// ADAMU-CUSTOM` | | DataModel + Initialization (CS entity'leri) | P4 | CS persistence (sahiplik/vergi) | ⏳ Planlanacak (EF migration gerekir) | | *(fazlar ilerledikçe eklenecek)* | | | | ## 10. Test stratejisi - Faz geçişleri için unit test (enjekte edilmiş saat ile zaman-güdümlü). - Kazanan belirleme + vergi hesabı unit testleri. - Tam döngü entegrasyon testi (sahte guild/oyuncu). - Remote-NPC + CS regresyon suit'i (merge güvenliği için). - Mobil uçtan uca: config dakikalık → emülatörde tam döngü; client'ın kapı/taht/sahiplik render'ını doğrula. ## 11. Aşamalı uygulama (alt-projeler) | Faz | Kapsam | Çıktı | |---|---|---| | **Faz 0** | Bootstrap: AdamuSw baseline + upstream remote + remote-NPC port + kendi image + DockerHub | Kendi image'imiz ayakta, custom NPC çalışıyor | | **P1** | Veri modeli + persistence + faz state machine + zamanlama + admin start/stop | İskelet: fazlar geçer, loglar (savaş yok) | | **P2** | Kayıt akışı (NPC, şartlar, guild mark, ücret) + protokol | Guild'ler kayıt olabilir | | **P3** | Kuşatma savaşı (harita, kapı, kristal, taht, PvP, kazanan) + protokol | Oynanabilir kuşatma | | **P4** | Sahiplik + vergi + sahibe özel av haritası + Guardian statue + protokol | Sahiplik ödülleri | | **P5** | AdminPanel UI + cila + tam mobil uçtan uca | Tamamlanmış CS | Her faz kendi spec (gerekirse) → plan → uygulama döngüsünü alır. **Sıradaki adım: Faz 0 için detaylı uygulama planı.** ## 12. Plan aşamasında netleştirilecek açık noktalar - CS haritasının kesin `WorldIndex`'i (`w_MapHeaders.h` / `GMBattleCastle`'dan doğrula). - Mevcut S6 CS paketlerinin kesin formatları (`WSclient.cpp` handler'larından çıkar). - OpenMU DataModel'e yeni kalıcı entity eklemenin kesin mekaniği (source generator + EF migration). - Alliance'ın kayıt/sahiplikte tam rolü (tek guild mi, alliance mı sahip olur). - Vergi hook'unun para akışında tam yeri (trade / personal store / NPC shop).