fix(go): repair migration wire contracts and runtime lifecycle; document incomplete port

This commit is contained in:
CAtlas0784 committed 2026-10-29 15:35:35 +07:00
1 parent e43a310617
commit 32e47014b5
35 files changed
+16826 -438

No files matched your search

+68 -20
View File
@@ -3,7 +3,9 @@ package gameserver
import (
"fmt"
"log"
"math"
"strings"
"time"
"ananta-ps/pkg/protocol"
)
@@ -48,6 +50,8 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
return "", fmt.Errorf("no active players in the game world")
}
targetSess := sessions[0] // Apply to primary active player
targetSess.stateMu.Lock()
defer targetSess.stateMu.Unlock()
switch cmd {
case "teleport", "tp":
@@ -55,15 +59,28 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
return "", fmt.Errorf("usage: teleport <poi_name> OR teleport <x> <y> <z>")
}
if poi, ok := KnownLandmarks[strings.ToLower(parts[1])]; ok {
_ = targetSess.Teleport(poi.X, poi.Y, poi.Z, poi.Facing)
if err := targetSess.teleport(poi.X, poi.Y, poi.Z, poi.Facing); err != nil {
return "", err
}
return fmt.Sprintf("Teleported to %s (%.1f, %.1f, %.1f)", poi.Name, poi.X, poi.Y, poi.Z), nil
}
if len(parts) >= 4 {
var x, y, z float32
_, _ = fmt.Sscanf(parts[1], "%f", &x)
_, _ = fmt.Sscanf(parts[2], "%f", &y)
_, _ = fmt.Sscanf(parts[3], "%f", &z)
_ = targetSess.Teleport(x, y, z, 0)
if _, err := fmt.Sscanf(parts[1], "%f", &x); err != nil {
return "", fmt.Errorf("invalid x coordinate")
}
if _, err := fmt.Sscanf(parts[2], "%f", &y); err != nil {
return "", fmt.Errorf("invalid y coordinate")
}
if _, err := fmt.Sscanf(parts[3], "%f", &z); err != nil {
return "", fmt.Errorf("invalid z coordinate")
}
if math.IsNaN(float64(x)) || math.IsInf(float64(x), 0) || math.IsNaN(float64(y)) || math.IsInf(float64(y), 0) || math.IsNaN(float64(z)) || math.IsInf(float64(z), 0) {
return "", fmt.Errorf("coordinates must be finite")
}
if err := targetSess.teleport(x, y, z, 0); err != nil {
return "", err
}
return fmt.Sprintf("Teleported to coordinates (%.1f, %.1f, %.1f)", x, y, z), nil
}
return "", fmt.Errorf("unknown POI landmark '%s'", parts[1])
@@ -73,8 +90,12 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
return "", fmt.Errorf("usage: weather <id> (e.g. 1=Sunny, 2=Rain, 3=Fog)")
}
var wId uint32
_, _ = fmt.Sscanf(parts[1], "%d", &wId)
ab.server.SetWorldWeather(wId)
if _, err := fmt.Sscanf(parts[1], "%d", &wId); err != nil {
return "", fmt.Errorf("invalid weather id")
}
if err := ab.server.SetWorldWeather(wId); err != nil {
return "", err
}
return fmt.Sprintf("World weather set to ID %d", wId), nil
case "time":
@@ -82,8 +103,12 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
return "", fmt.Errorf("usage: time <hour> (e.g. 12.0 for noon, 0.0 for midnight)")
}
var hour float32
_, _ = fmt.Sscanf(parts[1], "%f", &hour)
ab.server.SetWorldTimeOfDay(hour)
if _, err := fmt.Sscanf(parts[1], "%f", &hour); err != nil {
return "", fmt.Errorf("invalid hour")
}
if err := ab.server.SetWorldTimeOfDay(hour); err != nil {
return "", err
}
return fmt.Sprintf("World time set to %.1f:00", hour), nil
case "wanted":
@@ -95,7 +120,9 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
targetSess.wantedLevel = stars
w := protocol.NewUxWriter()
w.U64(targetSess.pid).U32(stars)
_ = targetSess.NotifyData(protocol.MethodGetMethodIDDefault("SyncWantedLevel", 68582860), w.Bytes())
if err := targetSess.NotifyData(protocol.MethodGetMethodIDDefault("SyncWantedLevel", 68582860), w.Bytes()); err != nil {
return "", err
}
return fmt.Sprintf("Player wanted level set to %d stars", stars), nil
case "spawn_vehicle", "veh":
@@ -103,11 +130,13 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
if len(parts) >= 2 {
_, _ = fmt.Sscanf(parts[1], "%d", &templateId)
}
vehUnitId := uint64(0x6000000000000000) | uint64(len(ab.server.sessions)+1)
vehUnitId := uint64(0x6000000000000000) | uint64(time.Now().UnixNano())
targetSess.activeVehicleId = vehUnitId
w := protocol.NewUxWriter()
w.U64(vehUnitId).U32(templateId).F32(targetSess.posX + 3.0).F32(targetSess.posY).F32(targetSess.posZ + 3.0).F32(targetSess.facing)
_ = targetSess.NotifyData(protocol.MethodGetMethodIDDefault("SyncSpawnVehicle", 68582851), w.Bytes())
if err := targetSess.NotifyData(protocol.MethodGetMethodIDDefault("SyncSpawnVehicle", 68582851), w.Bytes()); err != nil {
return "", err
}
return fmt.Sprintf("Spawned vehicle template %d (unit %d)", templateId, vehUnitId), nil
case "spawn_enemy":
@@ -119,15 +148,30 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
return "", fmt.Errorf("usage: switch <spirit_template_id>")
}
var newId uint32
_, _ = fmt.Sscanf(parts[1], "%d", &newId)
if _, err := fmt.Sscanf(parts[1], "%d", &newId); err != nil || newId == 0 {
return "", fmt.Errorf("invalid spirit template")
}
// Perform clean character swap
newUnitId := targetSess.unitId + 1
_ = targetSess.NotifyData(protocol.MethodSyncLogicAgentLeave, protocol.EncodeLogicAgentLeave(targetSess.unitId))
_ = targetSess.NotifyData(protocol.MethodSyncLogicAgentEnter, protocol.EncodeLogicAgentEnter(newUnitId))
_ = targetSess.NotifyData(protocol.MethodSyncManagedLogicAgent, protocol.EncodeManagedLogicAgent(newUnitId, targetSess.pid, 0))
if err := targetSess.NotifyData(protocol.MethodSyncLogicAgentLeave, protocol.EncodeLogicAgentLeave(targetSess.unitId)); err != nil {
return "", err
}
if err := targetSess.NotifyData(protocol.MethodSyncPlayerCurrentSpirit, protocol.EncodePlayerCurrentSpirit(targetSess.pid, newId, newUnitId, true)); err != nil {
return "", err
}
if err := targetSess.NotifyData(protocol.MethodSyncLogicAgentEnter, protocol.EncodeLogicAgentEnter(newUnitId)); err != nil {
return "", err
}
if err := targetSess.NotifyData(protocol.MethodSyncManagedLogicAgent, protocol.EncodeManagedLogicAgent(newUnitId, targetSess.pid, 0)); err != nil {
return "", err
}
newProj := protocol.EncodeRaidBattleUnitSpirit(newUnitId, newId, targetSess.posX, targetSess.posY, targetSess.posZ, targetSess.facing, targetSess.pid)
_ = targetSess.NotifyData(protocol.MethodSyncRaidBattleUnitSpirit, newProj)
_ = targetSess.NotifyData(protocol.MethodSyncPlayerCurrentSpirit, protocol.EncodePlayerCurrentSpirit(targetSess.pid, newId, newUnitId, true))
if err := targetSess.NotifyData(protocol.MethodSyncRaidBattleUnitSpirit, newProj); err != nil {
return "", err
}
if err := targetSess.NotifyData(protocol.MethodSyncPlayerCurrentSpirit, protocol.EncodePlayerCurrentSpirit(targetSess.pid, newId, newUnitId, true)); err != nil {
return "", err
}
targetSess.templateId = newId
targetSess.unitId = newUnitId
return fmt.Sprintf("Switched player character to template %d", newId), nil
@@ -135,13 +179,17 @@ func (ab *AdminBridge) ExecuteCommand(cmdLine string) (string, error) {
case "fog_unlock":
wFog := protocol.NewUxWriter()
wFog.U32(uint32(targetSess.activeScene)).Bool(true)
_ = targetSess.NotifyData(protocol.MethodSyncSceneFogMapAllUnlock, wFog.Bytes())
if err := targetSess.NotifyData(protocol.MethodSyncSceneFogMapAllUnlock, wFog.Bytes()); err != nil {
return "", err
}
return "All map fog unlocked", nil
case "dive_unlock":
wDive := protocol.NewUxWriter()
wDive.UxString("EnableDive").U8(0xFF).Int7(1).UxString("true")
_ = targetSess.NotifyData(protocol.MethodSyncRunGmUtils, wDive.Bytes())
if err := targetSess.NotifyData(protocol.MethodSyncRunGmUtils, wDive.Bytes()); err != nil {
return "", err
}
return "Diving mechanics enabled", nil
default: