fix(scene): unlock all teleports across maps, merge resource configs, fix scenary not load error, and add quick farm battle handlers
This commit is contained in:
1 parent
9aab62414f
commit
163d4433e6
47 files changed
+2025067
-6082
No files matched your search
@@ -2,6 +2,7 @@ package gameserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
@@ -11,56 +12,88 @@ import (
|
||||
|
||||
func init() {
|
||||
handle("StartCocoonStage", func(s *Session, req *goproto.StartCocoonStageCsReq, rsp *goproto.StartCocoonStageScRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] StartCocoonStage: CocoonId=%d Wave=%d WorldLevel=%d PropEntityId=%d", req.CocoonId, req.Wave, req.WorldLevel, req.PropEntityId))
|
||||
battleInfo := createBattleInfo(s, 0, 0)
|
||||
if req.WorldLevel > 0 {
|
||||
battleInfo.WorldLevel = req.WorldLevel
|
||||
}
|
||||
if req.Wave > 0 && int(req.Wave) <= len(battleInfo.MonsterWaveList) {
|
||||
battleInfo.MonsterWaveList = battleInfo.MonsterWaveList[:req.Wave]
|
||||
} else if len(battleInfo.MonsterWaveList) > 1 {
|
||||
battleInfo.MonsterWaveList = battleInfo.MonsterWaveList[:1]
|
||||
}
|
||||
battleInfo.JAOIOKBBMFC = uint32(len(battleInfo.MonsterWaveList))
|
||||
for _, w := range battleInfo.MonsterWaveList {
|
||||
w.WaveId = 1
|
||||
w.WaveParam = nil
|
||||
w.BattleStageId = battleInfo.StageId
|
||||
}
|
||||
normalizeCalyxBattleInfo(battleInfo, req.Wave, req.WorldLevel)
|
||||
CURRENT_BATTLE.Store(s.Token, battleInfo)
|
||||
|
||||
challengeCnt := req.Wave
|
||||
if challengeCnt == 0 {
|
||||
challengeCnt = 1
|
||||
}
|
||||
rsp.Retcode = 0
|
||||
rsp.PropEntityId = req.PropEntityId
|
||||
rsp.CocoonId = req.CocoonId
|
||||
rsp.Wave = req.Wave
|
||||
rsp.ChallengeCnt = challengeCnt
|
||||
rsp.BattleInfo = battleInfo
|
||||
return nil
|
||||
})
|
||||
|
||||
// NOTE: 4.6.51 proto names this message StartQuickCocoonStageCsReq/Rsp
|
||||
handleNamed("StartQuickCocoonStage", "StartQuickCocoonStageRsp", func(s *Session, req *goproto.StartQuickCocoonStageCsReq, rsp *goproto.StartQuickCocoonStageRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] StartQuickCocoonStage: CocoonId=%d Wave=%d WorldLevel=%d", req.CocoonId, req.Wave, req.WorldLevel))
|
||||
battleInfo := createBattleInfo(s, 0, 0)
|
||||
normalizeCalyxBattleInfo(battleInfo, req.Wave, req.WorldLevel)
|
||||
CURRENT_BATTLE.Store(s.Token, battleInfo)
|
||||
|
||||
rsp.Retcode = 0
|
||||
rsp.CocoonId = req.CocoonId
|
||||
rsp.Wave = req.Wave
|
||||
rsp.BattleInfo = battleInfo
|
||||
return nil
|
||||
})
|
||||
|
||||
// NOTE: 4.6.51 proto names this message StartQuickCocoonStageCsReq/Rsp
|
||||
// (the Rust code referenced an older QuickStartCocoonStage* name).
|
||||
handleNamed("StartQuickCocoonStage", "StartQuickCocoonStageRsp", func(s *Session, req *goproto.StartQuickCocoonStageCsReq, rsp *goproto.StartQuickCocoonStageRsp) error {
|
||||
handleNamed("StartQuickFarmElement", "StartQuickFarmElementRsp", func(s *Session, req *goproto.StartQuickFarmElementCsReq, rsp *goproto.StartQuickFarmElementRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] StartQuickFarmElement: FarmID=%d WorldLevel=%d", req.PAOFHFLFFHD, req.WorldLevel))
|
||||
battleInfo := createBattleInfo(s, 0, 0)
|
||||
if req.WorldLevel > 0 {
|
||||
battleInfo.WorldLevel = req.WorldLevel
|
||||
}
|
||||
if req.Wave > 0 && int(req.Wave) <= len(battleInfo.MonsterWaveList) {
|
||||
battleInfo.MonsterWaveList = battleInfo.MonsterWaveList[:req.Wave]
|
||||
} else if len(battleInfo.MonsterWaveList) > 1 {
|
||||
battleInfo.MonsterWaveList = battleInfo.MonsterWaveList[:1]
|
||||
}
|
||||
battleInfo.JAOIOKBBMFC = uint32(len(battleInfo.MonsterWaveList))
|
||||
for _, w := range battleInfo.MonsterWaveList {
|
||||
w.WaveId = 1
|
||||
w.WaveParam = nil
|
||||
w.BattleStageId = battleInfo.StageId
|
||||
}
|
||||
normalizeCalyxBattleInfo(battleInfo, 1, req.WorldLevel)
|
||||
CURRENT_BATTLE.Store(s.Token, battleInfo)
|
||||
|
||||
rsp.CocoonId = req.CocoonId
|
||||
rsp.Wave = req.Wave
|
||||
rsp.Retcode = 0
|
||||
rsp.PAOFHFLFFHD = req.PAOFHFLFFHD
|
||||
rsp.WorldLevel = req.WorldLevel
|
||||
rsp.BattleInfo = battleInfo
|
||||
return nil
|
||||
})
|
||||
|
||||
handle("ActiveFarmElement", func(s *Session, req *goproto.ActiveFarmElementCsReq, rsp *goproto.ActiveFarmElementScRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] ActiveFarmElement: EntityId=%d WorldLevel=%d", req.EntityId, req.WorldLevel))
|
||||
rsp.Retcode = 0
|
||||
rsp.EntityId = req.EntityId
|
||||
rsp.WorldLevel = req.WorldLevel
|
||||
return nil
|
||||
})
|
||||
|
||||
handle("DeactivateFarmElement", func(s *Session, req *goproto.DeactivateFarmElementCsReq, rsp *goproto.DeactivateFarmElementScRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] DeactivateFarmElement: EntityId=%d", req.EntityId))
|
||||
rsp.Retcode = 0
|
||||
rsp.EntityId = req.EntityId
|
||||
return nil
|
||||
})
|
||||
|
||||
handle("CocoonSweep", func(s *Session, req *goproto.CocoonSweepCsReq, rsp *goproto.CocoonSweepScRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] CocoonSweep: CocoonId=%d WorldLevel=%d", req.CocoonId, req.WorldLevel))
|
||||
rsp.Retcode = 0
|
||||
rsp.CocoonId = req.CocoonId
|
||||
rsp.DropData = &goproto.ItemList{}
|
||||
rsp.MultipleDropData = &goproto.ItemList{}
|
||||
return nil
|
||||
})
|
||||
|
||||
handle("FarmElementSweep", func(s *Session, req *goproto.FarmElementSweepCsReq, rsp *goproto.FarmElementSweepScRsp) error {
|
||||
Log(fmt.Sprintf("[BATTLE] FarmElementSweep: FarmID=%d", req.PAOFHFLFFHD))
|
||||
rsp.Retcode = 0
|
||||
rsp.PAOFHFLFFHD = req.PAOFHFLFFHD
|
||||
rsp.MultipleDropData = &goproto.ItemList{}
|
||||
return nil
|
||||
})
|
||||
|
||||
handle("GetFarmStageGachaInfo", func(s *Session, req *goproto.GetFarmStageGachaInfoCsReq, rsp *goproto.GetFarmStageGachaInfoScRsp) error {
|
||||
rsp.Retcode = 0
|
||||
return nil
|
||||
})
|
||||
|
||||
handle("SceneEnterStage", func(s *Session, req *goproto.SceneEnterStageCsReq, rsp *goproto.SceneEnterStageScRsp) error {
|
||||
battleInfo := createBattleInfo(s, 0, 0)
|
||||
CURRENT_BATTLE.Store(s.Token, battleInfo)
|
||||
@@ -152,19 +185,32 @@ func init() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if player := s.JSON(); player != nil && len(player.BattleConfig.Monsters) > 0 {
|
||||
battleInfo := createBattleInfo(s, 0, 0)
|
||||
CURRENT_BATTLE.Store(s.Token, battleInfo)
|
||||
rsp.Retcode = 0
|
||||
rsp.BattleInfo = battleInfo
|
||||
return nil
|
||||
}
|
||||
|
||||
rsp.Retcode = 2000 // RET_BATTLE_STAGE_NOT_MATCH
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func normalizeCalyxBattleInfo(battleInfo *goproto.SceneBattleInfo, reqWave uint32, worldLevel uint32) {
|
||||
if worldLevel > 0 {
|
||||
battleInfo.WorldLevel = worldLevel
|
||||
}
|
||||
if reqWave > 0 && int(reqWave) <= len(battleInfo.MonsterWaveList) {
|
||||
battleInfo.MonsterWaveList = battleInfo.MonsterWaveList[:reqWave]
|
||||
} else if len(battleInfo.MonsterWaveList) > 1 {
|
||||
battleInfo.MonsterWaveList = battleInfo.MonsterWaveList[:1]
|
||||
}
|
||||
battleInfo.JAOIOKBBMFC = uint32(len(battleInfo.MonsterWaveList))
|
||||
for _, w := range battleInfo.MonsterWaveList {
|
||||
// NOTE: In client 4.6.53 GameAssembly.dll 0x166b2fdd, client verifies:
|
||||
// (wave.WaveId & ~8) == 1. If wave_id != 1, it jumps to 0x166b3161
|
||||
// and throws NullReferenceException in AdventureModule.CreateBattleServerCheckResult.
|
||||
// Therefore every wave in Calyx / FarmElement MUST have WaveId = 1 and WaveParam = nil.
|
||||
w.WaveId = 1
|
||||
w.WaveParam = nil
|
||||
w.BattleStageId = battleInfo.StageId
|
||||
}
|
||||
}
|
||||
|
||||
// createBattleInfo is the Go port of battle.rs create_battle_info.
|
||||
func createBattleInfo(s *Session, casterID, skillIndex uint32) *goproto.SceneBattleInfo {
|
||||
player := s.JSON()
|
||||
|
||||
Reference in new issue
Block a user