200 lines
12 KiB
Markdown
200 lines
12 KiB
Markdown
# 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: <neden>` 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 <hub>/adamu-openmu:<tag> .
|
||
docker push <hub>/adamu-openmu:<tag>
|
||
# 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 |
|
||
| DataModel + Initialization (CS entity'leri) | P1 | CS persistence | ⏳ 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).
|