Files
2026-10-28 18:54:43 +07:00

200 lines
5.9 KiB
Go

package gameserver
import (
"fmt"
"strings"
"gac-hkrpg-go/internal/common"
goproto "gac-hkrpg-go/protocol/proto"
)
func init() {
// The three optional PlayerSettingInfo sub-messages are required by the
// Client requires these when processing _CmdGetBasicInfoScRsp.
handle("GetBasicInfo", func(s *Session, req *goproto.GetBasicInfoCsReq, rsp *goproto.GetBasicInfoScRsp) error {
rsp.Retcode = 0
player := s.JSON()
if player == nil {
return fmt.Errorf("GetBasicInfo requires player data")
}
rsp.Gender = uint32(player.MainCharacter.Gender())
rsp.IsGenderSet = true
rsp.PlayerSettingInfo = &goproto.PlayerSettingInfo{
OJPAODIHAJE: &goproto.PNOLLIAKGDB{
BELKCBAGMFC: false,
JHJKCJKDHIB: 0,
MLPGDPGIFCJ: false,
},
ANKIDJJINEI: &goproto.LJFJOGEEGPJ{
MBIAIMKHNDB: false,
},
CMFCOOEEECB: &goproto.JPGACKPLGCD{
KALACJBAPOA: false,
FOKJIPGMKAN: false,
IBLGOCFBOCO: false,
},
}
return nil
})
handle("PlayerHeartBeat", func(s *Session, req *goproto.PlayerHeartBeatCsReq, rsp *goproto.PlayerHeartBeatScRsp) error {
if err := s.applyCurrencyWarsCommands(); err != nil {
PacketLog("CW_GM deferred: " + err.Error())
}
rsp.ClientTimeMs = req.ClientTimeMs
rsp.ServerTimeMs = req.ClientTimeMs
var finalData []byte
finalData = append(finalData, heartbeatLua...)
if s.publicSDKURL != "" {
finalData = append(finalData, []byte("\n_G.__GAC_SRTOOL_LIVE_URL = "+luaQuotedString(s.publicSDKURL)+"\n")...)
}
profiles, err := loadNavigationProfiles()
if err != nil {
return err
}
finalData = append(finalData, profiles...)
if player := s.JSON(); player != nil {
finalData = append(finalData, []byte(fmt.Sprintf("\n_G.__GAC_NAVIGATION_CURRENT_ENTRY=%d\n", player.Scene.EntryID))...)
}
if probe := s.takeBattleProbe(); len(probe) > 0 {
finalData = append(finalData, '\n')
finalData = append(finalData, probe...)
}
if refresh, err := loadAARoundRefreshLua(s); err != nil {
PacketLog("AA round refresh withheld: " + err.Error())
} else {
finalData = append(finalData, refresh...)
}
if presentation, err := loadGachaPresentationLua(); err != nil {
PacketLog("GACHA presentation withheld: " + err.Error())
} else {
finalData = append(finalData, presentation...)
}
if camera, err := common.ReadFaceCamSettings(); err == nil {
finalData = append(finalData, []byte(fmt.Sprintf("\n_G.__GAC_CAMERA_SETTINGS={mode=%q,distance=%.3f}\n", camera.Mode, camera.Distance))...)
} else {
PacketLog("Camera settings withheld: " + err.Error())
}
luaScripts := common.ClientLuaScripts()
for _, script := range luaScripts {
finalData = append(finalData, '\n')
finalData = append(finalData, script.Data...)
}
if len(luaScripts) == 0 {
if freecam, err := common.ReadResourceFile("scripts/freecam.lua"); err == nil {
finalData = append(finalData, '\n')
finalData = append(finalData, freecam...)
}
}
rsp.DownloadData = &goproto.ClientDownloadData{
Version: goproto.ClientDownloadDataLuaVersion,
Time: int64(rsp.ServerTimeMs),
Data: finalData,
}
return nil
})
handle("PlayerLoginFinish", func(s *Session, req *goproto.PlayerLoginFinishCsReq, rsp *goproto.PlayerLoginFinishScRsp) error {
rsp.Retcode = 0
notify := &goproto.ContentPackageSyncDataScNotify{
Data: &goproto.ContentPackageData{},
}
for _, v := range contentPackageIDs {
notify.Data.ContentPackageList = append(notify.Data.ContentPackageList, &goproto.ContentPackageInfo{
Status: goproto.ContentPackageStatus_ContentPackageStatus_Finished,
ContentId: v,
})
}
return s.Send(notify)
})
handle("SyncClientResVersion", func(s *Session, req *goproto.SyncClientResVersionCsReq, rsp *goproto.SyncClientResVersionScRsp) error {
rsp.Retcode = 0
rsp.LJKMPIMKOMO = req.LJKMPIMKOMO
return nil
})
handle("GetPlayerBoardData", func(s *Session, req *goproto.GetPlayerBoardDataCsReq, rsp *goproto.GetPlayerBoardDataScRsp) error {
profile, err := loadProfileResources()
if err != nil {
return err
}
rsp.Retcode = 0
player, err := profilePlayer(s)
if err != nil {
return err
}
fillPlayerBoard(player, profile, rsp)
SceneDebugLog("GET_PLAYER_BOARD_DATA sent")
return nil
})
handle("GetPhoneData", func(s *Session, req *goproto.GetPhoneDataCsReq, rsp *goproto.GetPhoneDataScRsp) error {
profile, err := loadProfileResources()
if err != nil {
return err
}
rsp.Retcode = 0
player, err := profilePlayer(s)
if err != nil {
return err
}
fillPhoneData(player, profile, rsp)
SceneDebugLog("GET_PHONE_DATA sent")
return nil
})
}
var contentPackageIDs = []uint32{
200001, 200002, 200003, 200004, 200005, 200006, 200007, 200008, 200009, 200010,
200011, 200012, 200013, 200014, 150017, 150015, 150021, 150018, 130011, 130012,
130013, 150025, 140006, 150026, 130014, 150034, 150029, 150035, 150041, 150039,
150045, 150057, 150042, 150067, 150064, 150063, 150024, 171002, 150068, 150070,
150071, 150073, 150074, 150075, 150076, 150077, 150078, 150079, 150132, 150134,
150135,
}
const heartbeatLua = `local function beta_text()
local gameObject = CS.UnityEngine.GameObject.Find("UIRoot/AboveDialog/BetaHintDialog(Clone)")
if gameObject then
local textComponent = gameObject:GetComponentInChildren(typeof(CS.RPG.Client.LocalizedText))
if textComponent then
textComponent.text = "<color=#5C82DB><b>GaCy GO | แล้วเรามาเกกันนะ</b></color>"
end
end
end
beta_text()
`
func luaQuotedString(value string) string {
var out strings.Builder
out.Grow(len(value) + 2)
out.WriteByte('\'')
for _, r := range value {
switch r {
case '\\':
out.WriteString("\\\\")
case '\'':
out.WriteString("\\'")
case '\n':
out.WriteString("\\n")
case '\r':
out.WriteString("\\r")
case '\t':
out.WriteString("\\t")
default:
if r < 0x20 {
fmt.Fprintf(&out, "\\%03d", r)
} else {
out.WriteRune(r)
}
}
}
out.WriteByte('\'')
return out.String()
}