fix: sync current handlers, repair relic data and restore visible launcher consoles
This commit is contained in:
1 parent
163d4433e6
commit
74f3c4411b
46 files changed
+4599
-1402
No files matched your search
@@ -1,6 +1,7 @@
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"fmt"
|
||||
@@ -42,6 +43,10 @@ var BaseAvatarIDs = common.BaseAvatarIDs
|
||||
|
||||
type handlerFunc func(s *Session, payload []byte) error
|
||||
|
||||
// errResponseAlreadySent tells the typed dispatcher that the handler has
|
||||
// explicitly sent its response early to preserve packet ordering.
|
||||
var errResponseAlreadySent = errors.New("response already sent")
|
||||
|
||||
var (
|
||||
typedHandlers = map[uint16]handlerFunc{}
|
||||
dummyResponses = map[uint16]uint16{} // req cmd -> rsp cmd (empty body reply)
|
||||
@@ -59,12 +64,12 @@ func handle[ReqT any, RspT any](name string, fn func(s *Session, req *ReqT, rsp
|
||||
func handleNamed[ReqT any, RspT any](name, rspName string, fn func(s *Session, req *ReqT, rsp *RspT) error) {
|
||||
reqID, ok := goproto.CmdIDByName[name+"CsReq"]
|
||||
if !ok {
|
||||
Log("[DISPATCH] proto 4.6.51 has no " + name + "CsReq; handler skipped")
|
||||
Log("[DISPATCH] loaded protocol has no " + name + "CsReq; handler skipped")
|
||||
return
|
||||
}
|
||||
rspID, ok := goproto.CmdIDByName[rspName]
|
||||
if !ok {
|
||||
Log("[DISPATCH] proto 4.6.51 has no " + rspName + "; handler skipped")
|
||||
Log("[DISPATCH] loaded protocol has no " + rspName + "; handler skipped")
|
||||
return
|
||||
}
|
||||
typedHandlers[uint16(reqID)] = func(s *Session, payload []byte) error {
|
||||
@@ -78,7 +83,9 @@ func handleNamed[ReqT any, RspT any](name, rspName string, fn func(s *Session, r
|
||||
}
|
||||
}
|
||||
rsp := new(RspT)
|
||||
if err := fn(s, req, rsp); err != nil {
|
||||
if err := fn(s, req, rsp); errors.Is(err, errResponseAlreadySent) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.Send(any(rsp).(proto.Message))
|
||||
@@ -91,12 +98,25 @@ func dummy(name string) {
|
||||
reqID, ok1 := goproto.CmdIDByName[name+"CsReq"]
|
||||
rspID, ok2 := goproto.CmdIDByName[name+"ScRsp"]
|
||||
if !ok1 || !ok2 {
|
||||
Log("[DISPATCH] proto 4.6.51 has no dummy pair " + name + "; skipped")
|
||||
Log("[DISPATCH] loaded protocol has no dummy pair " + name + "; skipped")
|
||||
return
|
||||
}
|
||||
dummyResponses[uint16(reqID)] = uint16(rspID)
|
||||
}
|
||||
|
||||
// rawNamed binds only the request declared by the current command table.
|
||||
// Old numeric aliases can collide with responses after a protocol update.
|
||||
func rawNamed(request string, fn func(*Session, []byte) error) {
|
||||
id, ok := goproto.CmdIDByName[request]
|
||||
if !ok {
|
||||
panic("raw handler request missing from protocol: " + request)
|
||||
}
|
||||
if _, exists := rawHandlers[id]; exists {
|
||||
panic("duplicate raw handler: " + request)
|
||||
}
|
||||
rawHandlers[id] = fn
|
||||
}
|
||||
|
||||
// dangerFamilies are client modules that Sync(nil) -> NRE -> black screen when
|
||||
// they receive an empty ScRsp (lesson recorded in the Rust packet.rs / HANDOFF):
|
||||
// never auto-answer these, drop them silently instead.
|
||||
@@ -112,15 +132,8 @@ func isDangerCmd(cmdID uint16) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// CycleScore cmd ids (4143/4146) and GridFight range carry generic names
|
||||
switch cmdID {
|
||||
case 4143, 4146, 8541, 5410, 5449, 7142, 3174, 9252, 8175, 6995, 6988:
|
||||
return true
|
||||
}
|
||||
// GetMapRotationData: an empty reply NREs the client's map init
|
||||
// (AdventurePhase._EnterStep1_InitializeMapInfo) - drop until real
|
||||
// RotaterData is implemented
|
||||
if cmdID == 6827 {
|
||||
// This module requires populated rotation state before it can be answered.
|
||||
if name == "GetMapRotationDataCsReq" || strings.HasPrefix(name, "ChimeraGet") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
Reference in new issue
Block a user