fix(go): repair migration wire contracts and runtime lifecycle; document incomplete port
This commit is contained in:
1 parent
e43a310617
commit
32e47014b5
35 files changed
+16826
-438
No files matched your search
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user