package main import ( "encoding/hex" "fmt" "codehub.onpointcoding.net/sean/go-susapp/enum" "codehub.onpointcoding.net/sean/go-susapp/gamedata" "codehub.onpointcoding.net/sean/go-susapp/innernetobjects" "codehub.onpointcoding.net/sean/go-susapp/mapdata" "codehub.onpointcoding.net/sean/go-susapp/packets" "codehub.onpointcoding.net/sean/go-susapp/protocol" ) type GameDataProcessor struct { sus *SusApp gameRpcProcessor *GameRPCProcessor subpacketTagMap map[byte]func(net *protocol.PacketHandler, GameID int32, h *protocol.Hazel) } func NewGameDataProcessor(sus *SusApp) *GameDataProcessor { proc := &GameDataProcessor{sus: sus, gameRpcProcessor: NewGameRPCProcessor(sus)} proc.subpacketTagMap = map[byte]func(net *protocol.PacketHandler, GameID int32, h *protocol.Hazel){ 0x01: proc.captureGameData, 0x02: proc.captureGameRPC, 0x04: proc.captureGameSpawn, 0x05: proc.captureGameDespawn, } return proc } func (proc *GameDataProcessor) receiveGameDataSubpacket(net *protocol.PacketHandler, GameID int32, h []*protocol.Hazel) { for i := 0; i < len(h); i++ { v, ok := proc.subpacketTagMap[h[i].GetTag()] if ok { v(net, GameID, h[i]) } else { fmt.Printf("Unable to parse gamedata subpackets with tag of %x\n", h[i].GetTag()) fmt.Printf("Packet: %v\n", hex.EncodeToString(h[i].GetUnderlyingPacket().Dump())) } } } func (proc *GameDataProcessor) captureGameData(net *protocol.PacketHandler, GameID int32, h *protocol.Hazel) { a := &gamedata.DataH2G{} a.Read(h.GetUnderlyingPacket()) netId := a.Component.NetID if netId != 0 { b, ok := proc.sus.state.CurrentGame.NetObjects[netId] if ok { (*b).Read(a.Component.RawData, false) } } } func (proc *GameDataProcessor) captureGameRPC(net *protocol.PacketHandler, GameID int32, h *protocol.Hazel) { proc.gameRpcProcessor.receiveGameRpcCall(net, GameID, gamedata.NewRpcFromHazel(h)) } func (proc *GameDataProcessor) captureGameSpawn(net *protocol.PacketHandler, GameID int32, h *protocol.Hazel) { a := &gamedata.SpawnH2G{} a.Read(h.GetUnderlyingPacket()) if len(a.Components) >= 1 { z := a.Components[0] netId := z.NetID switch a.SpawnType { case enum.SPAWNTYPE_GAME_DATA: b := &innernetobjects.GameData{} b.Read(z.ComponentData.GetUnderlyingPacket(), true) var c innernetobjects.InnerNetObject = b proc.sus.state.CurrentGame.NetObjects[netId] = &c proc.sus.state.CurrentGame.GameDataNetID = netId fmt.Printf("GameData Net ID: %v\n", netId) case enum.SPAWNTYPE_SKELD_SHIP_STATUS: b := innernetobjects.NewSkeldShipStatus() b.Read(z.ComponentData.GetUnderlyingPacket(), true) var c innernetobjects.InnerNetObject = b proc.sus.state.CurrentGame.NetObjects[netId] = &c proc.sus.state.CurrentGame.MapNetObjectNetID = netId fmt.Printf("SkeldShipStatus Net ID: %v\n", netId) case enum.SPAWNTYPE_MIRA_SHIP_STATUS: b := innernetobjects.NewMiraShipStatus() b.Read(z.ComponentData.GetUnderlyingPacket(), true) var c innernetobjects.InnerNetObject = b proc.sus.state.CurrentGame.NetObjects[netId] = &c proc.sus.state.CurrentGame.MapNetObjectNetID = netId fmt.Printf("MiraShipStatus Net ID: %v\n", netId) case enum.SPAWNTYPE_POLUS_SHIP_STATUS: b := innernetobjects.NewPolusShipStatus() b.Read(z.ComponentData.GetUnderlyingPacket(), true) var c innernetobjects.InnerNetObject = b proc.sus.state.CurrentGame.NetObjects[netId] = &c proc.sus.state.CurrentGame.MapNetObjectNetID = netId fmt.Printf("PolusShipStatus Net ID: %v\n", netId) case enum.SPAWNTYPE_PLAYER_CONTROL: b := &innernetobjects.PlayerControl{} b.Read(z.ComponentData.GetUnderlyingPacket(), true) var c innernetobjects.InnerNetObject = b proc.sus.state.CurrentGame.NetObjects[netId] = &c y := &PlayerObject{} proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerNetID[netId] = y proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerClientID[a.OwnerID] = y proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerClientID[a.OwnerID].PlayerClientNetID = netId proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerClientID[a.OwnerID].PlayerControllerNetID = netId fmt.Printf("Player Net ID: %v\n", netId) fmt.Printf("Player Owner ID: %v\n", a.OwnerID) isMyPlayer := a.OwnerID == proc.sus.state.CurrentGame.ClientID if isMyPlayer { fmt.Println("Owner ID matches current Client ID so its my player controller") proc.sus.state.CurrentGame.ClientPlayerNetID = z.NetID // Send RPC CheckName proc.sus.state.CurrentGame.CheckNameNonce = net.GetNonce() var d1 gamedata.RpcSub = &gamedata.RpcCheckName{Name: proc.sus.state.Settings.PlayerName} var d2 packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(proc.sus.state.CurrentGame.ClientPlayerNetID, &d1) var d3 protocol.HazelPayload = packets.NewGameDataToSingleSubpacket(proc.sus.state.CurrentGame.GameID, proc.sus.state.CurrentGame.HostClientID, &d2) net.SendReliablePacket(proc.sus.state.CurrentGame.CheckNameNonce, []*protocol.Hazel{protocol.NewHazelFromPayload(&d3)}) // Send RPC CheckColor proc.sus.state.CurrentGame.CheckColorNonce = net.GetNonce() var e1 gamedata.RpcSub = &gamedata.RpcCheckColor{Color: proc.sus.state.Settings.PlayerColor} var e2 packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(proc.sus.state.CurrentGame.ClientPlayerNetID, &e1) var e3 protocol.HazelPayload = packets.NewGameDataToSingleSubpacket(proc.sus.state.CurrentGame.GameID, proc.sus.state.CurrentGame.HostClientID, &e2) net.SendReliablePacket(proc.sus.state.CurrentGame.CheckColorNonce, []*protocol.Hazel{protocol.NewHazelFromPayload(&e3)}) } if len(a.Components) >= 2 { y := a.Components[1].NetID d := innernetobjects.PlayerPhysics{} d.Read(a.Components[1].ComponentData.GetUnderlyingPacket(), true) var e innernetobjects.InnerNetObject = &d proc.sus.state.CurrentGame.NetObjects[y] = &e proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerClientID[a.OwnerID].PlayerPhysicsNetID = y } if len(a.Components) >= 3 { y := a.Components[2].NetID d := innernetobjects.PlayerNetworkTransform{} d.Read(a.Components[2].ComponentData.GetUnderlyingPacket(), true) var e innernetobjects.InnerNetObject = &d proc.sus.state.CurrentGame.NetObjects[y] = &e proc.sus.state.CurrentGame.PlayerNetObjects.ByPlayerClientID[a.OwnerID].PlayerNetworkTransform = y if isMyPlayer { d.TargetPosition = mapdata.LobbySpawnPositions[int(b.PlayerID)%len(mapdata.LobbySpawnPositions)] proc.sus.movementProcessor.Tick(0) } } } } } func (proc *GameDataProcessor) captureGameDespawn(net *protocol.PacketHandler, GameID int32, h *protocol.Hazel) { }