Final commit

This commit is contained in:
Melon 2022-06-25 11:59:37 +01:00
parent 0ba6d712d3
commit b39cacef6d
Signed by: melon
GPG Key ID: B0ADD5395BCDAAB6
25 changed files with 394 additions and 277 deletions

View File

@ -126,14 +126,14 @@ func (proc *GameDataProcessor) captureGameSpawn(net *protocol.PacketHandler, Gam
// Send RPC CheckName // Send RPC CheckName
proc.sus.state.CurrentGame.CheckNameNonce = net.GetNonce() proc.sus.state.CurrentGame.CheckNameNonce = net.GetNonce()
var d1 gamedata.RpcSub = &gamedata.RpcCheckName{Name: proc.sus.state.Settings.PlayerName} 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 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) 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)}) net.SendReliablePacket(proc.sus.state.CurrentGame.CheckNameNonce, []*protocol.Hazel{protocol.NewHazelFromPayload(&d3)})
// Send RPC CheckColor // Send RPC CheckColor
proc.sus.state.CurrentGame.CheckColorNonce = net.GetNonce() proc.sus.state.CurrentGame.CheckColorNonce = net.GetNonce()
var e1 gamedata.RpcSub = &gamedata.RpcCheckColor{Color: proc.sus.state.Settings.PlayerColor} 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 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) 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)}) net.SendReliablePacket(proc.sus.state.CurrentGame.CheckColorNonce, []*protocol.Hazel{protocol.NewHazelFromPayload(&e3)})
} }

2
go.mod
View File

@ -12,6 +12,7 @@ replace (
tea.melonie54.xyz/sean/go-susapp/src/protocol => ./src/protocol tea.melonie54.xyz/sean/go-susapp/src/protocol => ./src/protocol
tea.melonie54.xyz/sean/go-susapp/src/systemtypes => ./src/systemtypes tea.melonie54.xyz/sean/go-susapp/src/systemtypes => ./src/systemtypes
tea.melonie54.xyz/sean/go-susapp/src/util => ./src/util tea.melonie54.xyz/sean/go-susapp/src/util => ./src/util
tea.melonie54.xyz/sean/go-susapp/src/version => ./src/version
) )
require ( require (
@ -24,6 +25,7 @@ require (
tea.melonie54.xyz/sean/go-susapp/src/packets v0.0.0-20211216203152-cbba9006e452 tea.melonie54.xyz/sean/go-susapp/src/packets v0.0.0-20211216203152-cbba9006e452
tea.melonie54.xyz/sean/go-susapp/src/protocol v0.0.0 tea.melonie54.xyz/sean/go-susapp/src/protocol v0.0.0
tea.melonie54.xyz/sean/go-susapp/src/util v0.0.0 tea.melonie54.xyz/sean/go-susapp/src/util v0.0.0
tea.melonie54.xyz/sean/go-susapp/src/version v0.0.0-20211217150321-0ba6d712d37d
) )
require tea.melonie54.xyz/sean/go-susapp/src/systemtypes v0.0.0 // indirect require tea.melonie54.xyz/sean/go-susapp/src/systemtypes v0.0.0 // indirect

View File

@ -124,7 +124,7 @@ func (proc *PacketProcessor) captureUnreliableGameDataTo(net *protocol.PacketHan
func (proc *PacketProcessor) captureJoinedGame(net *protocol.PacketHandler, nonce uint16, h *protocol.Hazel) { func (proc *PacketProcessor) captureJoinedGame(net *protocol.PacketHandler, nonce uint16, h *protocol.Hazel) {
a := &packets.JoinedGameH2C{} a := &packets.JoinedGameH2C{}
a.Read(h.GetUnderlyingPacket()) a.Read(h.GetUnderlyingPacket())
fmt.Printf("Joined game: %v\n", a.GameID) fmt.Printf("Joined game: %v\n", util.CodeFromGameID(a.GameID))
fmt.Printf("Client id: %v\n", a.JoinedClientID) fmt.Printf("Client id: %v\n", a.JoinedClientID)
fmt.Printf("Host client id: %v\n", a.HostClientID) fmt.Printf("Host client id: %v\n", a.HostClientID)
proc.sus.state.CurrentGame = &CurrentGameData{ proc.sus.state.CurrentGame = &CurrentGameData{
@ -142,11 +142,8 @@ func (proc *PacketProcessor) captureJoinedGame(net *protocol.PacketHandler, nonc
proc.sus.state.Screen = enum.SCREEN_LOBBY proc.sus.state.Screen = enum.SCREEN_LOBBY
proc.sus.state.LoadCollision("lobby") proc.sus.state.LoadCollision("lobby")
// Send platform // Send active pod type
var b1 packets.GameDataSubpacket = &gamedata.ClientInfoC2S{ var b1 packets.GameDataSubpacket = &gamedata.SetActivePodType{PodType: "mira"} // TODO: don't hard code this
ClientID: proc.sus.state.CurrentGame.ClientID,
PlatformID: enum.PLATFORM_LinuxPlayer,
}
var b2 protocol.HazelPayload = packets.NewGameDataSingleSubpacket(proc.sus.state.CurrentGame.GameID, &b1) var b2 protocol.HazelPayload = packets.NewGameDataSingleSubpacket(proc.sus.state.CurrentGame.GameID, &b1)
net.SendReliablePacket(net.GetNonce(), []*protocol.Hazel{protocol.NewHazelFromPayload(&b2)}) net.SendReliablePacket(net.GetNonce(), []*protocol.Hazel{protocol.NewHazelFromPayload(&b2)})
@ -157,12 +154,20 @@ func (proc *PacketProcessor) captureJoinedGame(net *protocol.PacketHandler, nonc
} }
var c2 protocol.HazelPayload = packets.NewGameDataSingleSubpacket(proc.sus.state.CurrentGame.GameID, &c1) var c2 protocol.HazelPayload = packets.NewGameDataSingleSubpacket(proc.sus.state.CurrentGame.GameID, &c1)
net.SendReliablePacket(net.GetNonce(), []*protocol.Hazel{protocol.NewHazelFromPayload(&c2)}) net.SendReliablePacket(net.GetNonce(), []*protocol.Hazel{protocol.NewHazelFromPayload(&c2)})
var d1 packets.GameDataSubpacket = gamedata.NewRpcFromRpcSubs(proc.sus.state.CurrentGame.HostClientID, []gamedata.RpcSub{
&gamedata.RpcSetHat{HatID: "hat_pk04_Bear"},
&gamedata.RpcSetPet{PetID: "pet_Robot"},
&gamedata.RpcSetSkin{SkinID: "skin_Winter"},
})
var d2 protocol.HazelPayload = packets.NewGameDataSingleSubpacket(proc.sus.state.CurrentGame.GameID, &d1)
net.SendReliablePacket(net.GetNonce(), []*protocol.Hazel{protocol.NewHazelFromPayload(&d2)})
} }
func (proc *PacketProcessor) captureAlterGame(net *protocol.PacketHandler, nonce uint16, h *protocol.Hazel) { func (proc *PacketProcessor) captureAlterGame(net *protocol.PacketHandler, nonce uint16, h *protocol.Hazel) {
a := &packets.AlterGameH2G{} a := &packets.AlterGameH2G{}
a.Read(h.GetUnderlyingPacket()) a.Read(h.GetUnderlyingPacket())
fmt.Printf("Alter game: %v\n", a.GameID) fmt.Printf("Alter game: %v\n", util.CodeFromGameID(a.GameID))
fmt.Printf("Tag ID: %v\n", a.TagID) fmt.Printf("Tag ID: %v\n", a.TagID)
fmt.Printf("Tag value: %v\n", a.TagValue) fmt.Printf("Tag value: %v\n", a.TagValue)
if a.GameID == proc.sus.state.CurrentGame.GameID && a.TagID == 1 { if a.GameID == proc.sus.state.CurrentGame.GameID && a.TagID == 1 {

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"math" "math"
"strconv" "strconv"
"tea.melonie54.xyz/sean/go-susapp/src/version"
"time" "time"
"tea.melonie54.xyz/sean/go-susapp/src/enum" "tea.melonie54.xyz/sean/go-susapp/src/enum"
@ -41,7 +40,7 @@ func (r *Renderer) Draw(da *gtk.DrawingArea, cr *cairo.Context) {
r.w = float64(allocation.GetWidth()) r.w = float64(allocation.GetWidth())
r.h = float64(allocation.GetHeight()) r.h = float64(allocation.GetHeight())
versionText := version.GetVersionFormatted(r.state.Version) versionText := r.state.Version.Formatted()
// Background // Background
r.DrawFilledRectangle(0, 0, r.w, r.h, 0x14181c) r.DrawFilledRectangle(0, 0, r.w, r.h, 0x14181c)

View File

@ -1,119 +0,0 @@
package enum
const (
HAT_NONE = 0
HAT_ASTRONAUT = 1
HAT_BASEBALL_CAP = 2
HAT_BRAIN_SLUG = 3
HAT_BUSH_HAT = 4
HAT_CAPTAIN_HAT = 5
HAT_DOUBLE_TOP_HAT = 6
HAT_FLOWERPOT = 7
HAT_GOGGLES = 8
HAT_HARD_HAT = 9
HAT_MILITARY_HAT = 10
HAT_PAPER_HAT = 11
HAT_PARTY_HAT = 12
HAT_POLICE_HAT = 13
HAT_STETHOSCOPE = 14
HAT_TOP_HAT = 15
HAT_TOWEL_WIZARD = 16
HAT_USHANKA = 17
HAT_VIKING = 18
HAT_WALL_GUARD_CAP = 19
HAT_SNOWMAN = 20
HAT_REINDEER_ANTLERS = 21
HAT_CHRISTMAS_LIGHTS = 22
HAT_SANTA_HAT = 23
HAT_CHRISTMAS_TREE = 24
HAT_CHRISTMAS_PRESENT = 25
HAT_CANDY_CANES = 26
HAT_ELF_HAT = 27
HAT_NEW_YEARS_2018 = 28
HAT_WHITE_HAT = 29
HAT_CROWN = 30
HAT_EYEBROWS = 31
HAT_HALO = 32
HAT_HERO_CAP = 33
HAT_PIP_CAP = 34
HAT_PLUNGER = 35
HAT_SCUBA_MASK = 36
HAT_HENRY_STICKMIN = 37
HAT_STRAW_HAT = 38
HAT_TEN_GALLON_HAT = 39
HAT_THIRD_EYE = 40
HAT_TOILET_PAPER = 41
HAT_TOPPAT_CLAN_LEADER = 42
HAT_BLACK_FEDORA = 43
HAT_SKI_GOGGLES = 44
HAT_HEARING_PROTECTION = 45
HAT_HAZMAT_MASK = 46
HAT_FACE_MASK = 47
HAT_MIRA_SECURITY_CAP = 48
HAT_SAFARI_HAT = 49
HAT_BANANA = 50
HAT_BEANIE = 51
HAT_BEAR_EARS = 52
HAT_CHEESE = 53
HAT_CHERRY = 54
HAT_EGG = 55
HAT_GREEN_FEDORA = 56
HAT_FLAMINGO = 57
HAT_FLOWER_PIN = 58
HAT_KNIGHT_HELMET = 59
HAT_PLANT = 60
HAT_BAT_EYES = 61
HAT_BAT_WINGS = 62
HAT_HORNS = 63
HAT_MOHAWK = 64
HAT_PUMPKIN = 65
HAT_SCARY_PAPER_BAG = 66
HAT_WITCH_HAT = 67
HAT_WOLF_EARS = 68
HAT_PIRATE_HAT = 69
HAT_PLAGUE_DOCTOR = 70
HAT_MACHETE = 71
HAT_HOCKEY_MASK = 72
HAT_MINER_HELMET = 73
HAT_WINTER_CAP = 74
HAT_ARCHAEOLOGIST_HAT = 75
HAT_ANTENNA = 76
HAT_BALLOON = 77
HAT_BIRD_NEST = 78
HAT_BLACK_BELT = 79
HAT_CAUTION_SIGN = 80
HAT_CHEF_HAT = 81
HAT_COP_HAT = 82
HAT_DO_RAG = 83
HAT_DUM_STICKER = 84
HAT_FEZ = 85
HAT_GENERAL_HAT = 86
HAT_POMPADOUR_HAIR = 87
HAT_HUNTER_HAT = 88
HAT_JUNGLE_HAT = 89
HAT_MINI_CREWMATE = 90
HAT_NINJA_MASK = 91
HAT_RAM_HORNS = 92
HAT_MINI_CREWMATE_SNOWMAN = 93
HAT_GEOFF_KEIGHLEY_MASK = 94
HAT_DAVE_PANPA_CAP = 95
HAT_ELLIE_ROSE_HAIR = 96
HAT_SVEN_SVENSSON_HAT = 97
HAT_BURT_CURTIS_HAT = 98
HAT_ELLRY_MOHAWK = 99
HAT_THOMAS_CHESTERSHIRE_MONOCLES = 100
HAT_WIZARD_HAT = 101
HAT_FREDRICK_MUENSTER_HAT = 102
HAT_MR_MACBETH_HAT = 103
HAT_TOPPAT_HENRY_STICKMIN_HAT = 104
HAT_TOPPAT_ELLIE_ROSE_HAT = 105
HAT_GEOFFREY_PLUMB_HAT = 106
HAT_ANGRY_EYEBROWS = 107
HAT_CHOCOLATE_ICE_CREAM = 108
HAT_HEART_PIN = 109
HAT_PONYTAIL = 110
HAT_RUBBER_GLOVE = 111
HAT_UNICORN_HORN = 112
HAT_ZIPPER = 113
HAT_RIGHT_HAND_MAN_HAT = 114
)

View File

@ -1,16 +0,0 @@
package enum
const (
PET_NONE = 0
PET_ALIEN = 1
PET_MINI_CREWMATE = 2
PET_DOG = 3
PET_HENRY_STICKMIN = 4
PET_HAMSTER = 5
PET_ROBOT = 6
PET_UFO = 7
PET_ELLIE_ROSE = 8
PET_SQUIG = 9
PET_BEDCRAB = 10
PET_GLITCH = 11
)

View File

@ -1,24 +1,15 @@
package enum package enum
const ( const (
PLATFORM_OSXEditor = 0 PLATFORM_UNKNOWN = 0
PLATFORM_OSXPlayer = 1 PLATFORM_STANDALONE_EPIC_PC = 1
PLATFORM_WindowsPlayer = 2 PLATFORM_STANDALONE_STEAM_PC = 1
PLATFORM_WindowsEditor = 7 PLATFORM_STANDALONE_MAC = 3
PLATFORM_IPhonePlayer = 8 PLATFORM_STANDALONE_WIN10 = 4
PLATFORM_Android = 11 PLATFORM_STANDALONE_ITCH = 5
PLATFORM_LinuxPlayer = 13 PLATFORM_IPHONE = 6
PLATFORM_LinuxEditor = 16 PLATFORM_ANDROID = 7
PLATFORM_WebGLPlayer = 17 PLATFORM_SWITCH = 8
PLATFORM_WSAPlayerX86 = 18 PLATFORM_XBOX = 9
PLATFORM_WSAPlayerX64 = 19 PLATFORM_PLAYSTATION = 10
PLATFORM_WSAPlayerARM = 20
PLATFORM_PS4 = 25
PLATFORM_XboxOne = 27
PLATFORM_tvOS = 31
PLATFORM_Switch = 32
PLATFORM_Lumin = 33
PLATFORM_Stadia = 34
PLATFORM_CloudRendering = 35
PLATFORM_PS5 = 36
) )

View File

@ -0,0 +1,8 @@
package enum
const (
PLAYER_OUTFIT_TYPE_DEFAULT = 0
PLAYER_OUTFIT_TYPE_SHAPESHIFTED = 1
)
type PlayerOutfitType byte

10
src/enum/roletypes.go Normal file
View File

@ -0,0 +1,10 @@
package enum
const (
ROLE_TYPES_CREWMATE = 0
ROLE_TYPES_IMPOSTOR = 1
ROLE_TYPES_SCIENTIST = 2
ROLE_TYPES_ENGINEER = 3
ROLE_TYPES_GUARDIAN_ANGEL = 4
ROLE_TYPES_SHAPESHIFTER = 5
)

View File

@ -10,15 +10,15 @@ const (
RPC_SET_NAME = 0x06 RPC_SET_NAME = 0x06
RPC_CHECK_COLOR = 0x07 RPC_CHECK_COLOR = 0x07
RPC_SET_COLOR = 0x08 RPC_SET_COLOR = 0x08
RPC_SET_HAT = 0x09 RPC_OLD_SET_HAT = 0x09
RPC_SET_SKIN = 0x0a RPC_OLD_SET_SKIN = 0x0a
RPC_REPORT_DEAD_BODY = 0x0b RPC_REPORT_DEAD_BODY = 0x0b
RPC_MURDER_PLAYER = 0x0c RPC_MURDER_PLAYER = 0x0c
RPC_SEND_CHAT = 0x0d RPC_SEND_CHAT = 0x0d
RPC_START_MEETING = 0x0e RPC_START_MEETING = 0x0e
RPC_SET_SCANNER = 0x0f RPC_SET_SCANNER = 0x0f
RPC_SEND_CHAT_NOTE = 0x10 RPC_SEND_CHAT_NOTE = 0x10
RPC_SET_PET = 0x11 RPC_OLD_SET_PET = 0x11
RPC_SET_START_COUNTER = 0x12 RPC_SET_START_COUNTER = 0x12
RPC_ENTER_VENT = 0x13 RPC_ENTER_VENT = 0x13
RPC_EXIT_VENT = 0x14 RPC_EXIT_VENT = 0x14
@ -33,4 +33,18 @@ const (
RPC_SET_TASKS = 0x1d RPC_SET_TASKS = 0x1d
RPC_CLIMB_LADDER = 0x1f RPC_CLIMB_LADDER = 0x1f
RPC_USE_PLATFORM = 0x20 RPC_USE_PLATFORM = 0x20
RPC_SEND_QUICK_CHAT = 0x21
RPC_BOOT_FROM_VENT = 0x22
RPC_UPDATE_SYSTEM = 0x23
RPC_SET_LEVEL = 0x26
RPC_SET_HAT = 0x27
RPC_SET_SKIN = 0x28
RPC_SET_PET = 0x29
RPC_SET_VISOR = 0x2a
RPC_SET_NAMEPLATE = 0x2b
RPC_SET_ROLE = 0x2c
RPC_PROTECT_PLAYER = 0x2d
RPC_SHAPESHIFT = 0x2e
RPC_CHECK_MURDER = 0x2f
RPC_CHECK_PROTECT = 0x30
) )

View File

@ -1,23 +0,0 @@
package enum
const (
SKIN_NONE = 0
SKIN_ASTRONAUT = 1
SKIN_CAPTAIN = 2
SKIN_MECHANIC = 3
SKIN_MILITARY = 4
SKIN_POLICE = 5
SKIN_SCIENTIST = 6
SKIN_SUIT_BLACK = 7
SKIN_SUIT_WHITE = 8
SKIN_WALL_GUARD = 9
SKIN_HAZMAT = 10
SKIN_SECURITY_GUARD = 11
SKIN_TARMAC = 12
SKIN_MINER = 13
SKIN_WINTER = 14
SKIN_ARCHAEOLOGIST = 15
SKIN_PRISONER = 16
SKIN_CCC = 17
SKIN_RIGHT_HAND_MAN_REBORN = 18
)

View File

@ -12,24 +12,25 @@ import (
type Rpc struct { type Rpc struct {
SenderNetID uint32 SenderNetID uint32
RPCCallID byte Subs []RpcSub
Sub *RpcSub
UnderlyingHazel *protocol.Hazel UnderlyingHazel *protocol.Hazel
} }
func NewRpcFromHazel(h *protocol.Hazel) *Rpc { func NewRpcFromHazel(h *protocol.Hazel) *Rpc {
a := &Rpc{} a := &Rpc{}
a.SenderNetID = h.GetUnderlyingPacket().ReadPackedUInt32() a.SenderNetID = h.GetUnderlyingPacket().ReadPackedUInt32()
a.RPCCallID = h.GetUnderlyingPacket().Read()
a.UnderlyingHazel = h a.UnderlyingHazel = h
return a return a
} }
func NewRpcFromRpcSub(senderNetID uint32, sub *RpcSub) *Rpc { func NewRpcFromRpcSub(senderNetID uint32, sub RpcSub) *Rpc {
return NewRpcFromRpcSubs(senderNetID, []RpcSub{sub})
}
func NewRpcFromRpcSubs(senderNetID uint32, subs []RpcSub) *Rpc {
return &Rpc{ return &Rpc{
SenderNetID: senderNetID, SenderNetID: senderNetID,
RPCCallID: (*sub).CallCode(), Subs: subs,
Sub: sub,
} }
} }
@ -45,13 +46,24 @@ func (d *Rpc) AsHazel() *protocol.Hazel {
func (d *Rpc) TypeCode() byte { return 0x02 } func (d *Rpc) TypeCode() byte { return 0x02 }
func (d *Rpc) Write(packet *protocol.Packet) { func (d *Rpc) Write(packet *protocol.Packet) {
packet.WritePackedUInt32(d.SenderNetID) packet.WritePackedUInt32(d.SenderNetID)
packet.Write(d.RPCCallID) for i := range d.Subs {
(*d.Sub).WriteToPacket(packet) packet.Write(d.Subs[i].CallCode())
d.Subs[i].WriteToPacket(packet)
}
} }
func (d *Rpc) Read(packet *protocol.Packet) { func (d *Rpc) Read(packet *protocol.Packet) {
d.SenderNetID = packet.ReadPackedUInt32() d.SenderNetID = packet.ReadPackedUInt32()
d.RPCCallID = packet.Read() for packet.Remaining() > 0 {
// TODO: finish this k := packet.Read()
var v RpcSub
switch k {
case 0x00:
v = &RpcPlayAnimation{}
}
if v != nil {
v.ReadFromPacket(packet)
}
}
} }
type RpcSub interface { type RpcSub interface {
@ -166,26 +178,6 @@ func (d *RpcSetColor) CallCode() byte { return enum.RPC_
func (d *RpcSetColor) WriteToPacket(packet *protocol.Packet) { packet.Write(d.Color) } func (d *RpcSetColor) WriteToPacket(packet *protocol.Packet) { packet.Write(d.Color) }
func (d *RpcSetColor) ReadFromPacket(packet *protocol.Packet) { d.Color = packet.Read() } func (d *RpcSetColor) ReadFromPacket(packet *protocol.Packet) { d.Color = packet.Read() }
//
// 0x09 RpcSetHat
//
type RpcSetHat struct{ HatID uint32 }
func (d *RpcSetHat) CallCode() byte { return enum.RPC_SET_HAT }
func (d *RpcSetHat) WriteToPacket(packet *protocol.Packet) { packet.WritePackedUInt32(d.HatID) }
func (d *RpcSetHat) ReadFromPacket(packet *protocol.Packet) { d.HatID = packet.ReadPackedUInt32() }
//
// 0x0a RpcSetSkin
//
type RpcSetSkin struct{ SkinID uint32 }
func (d *RpcSetSkin) CallCode() byte { return enum.RPC_SET_SKIN }
func (d *RpcSetSkin) WriteToPacket(packet *protocol.Packet) { packet.WritePackedUInt32(d.SkinID) }
func (d *RpcSetSkin) ReadFromPacket(packet *protocol.Packet) { d.SkinID = packet.ReadPackedUInt32() }
// //
// 0x0b RpcReportDeadBody // 0x0b RpcReportDeadBody
// //
@ -270,16 +262,6 @@ func (d *RpcSendChatNote) ReadFromPacket(packet *protocol.Packet) {
d.ChatNoteType = packet.Read() d.ChatNoteType = packet.Read()
} }
//
// 0x11 RpcSetPet
//
type RpcSetPet struct{ PetID uint32 }
func (d *RpcSetPet) CallCode() byte { return enum.RPC_SET_PET }
func (d *RpcSetPet) WriteToPacket(packet *protocol.Packet) { packet.WritePackedUInt32(d.PetID) }
func (d *RpcSetPet) ReadFromPacket(packet *protocol.Packet) { d.PetID = packet.ReadPackedUInt32() }
// //
// 0x12 RpcSetStartCounter // 0x12 RpcSetStartCounter
// //
@ -499,3 +481,44 @@ type RpcUsePlatform struct{}
func (d *RpcUsePlatform) CallCode() byte { return enum.RPC_CLIMB_LADDER } func (d *RpcUsePlatform) CallCode() byte { return enum.RPC_CLIMB_LADDER }
func (d *RpcUsePlatform) WriteToPacket(packet *protocol.Packet) {} func (d *RpcUsePlatform) WriteToPacket(packet *protocol.Packet) {}
func (d *RpcUsePlatform) ReadFromPacket(packet *protocol.Packet) {} func (d *RpcUsePlatform) ReadFromPacket(packet *protocol.Packet) {}
//
// 0x27 RpcSetHat
//
type RpcSetHat struct{ HatID string }
func (d *RpcSetHat) CallCode() byte { return enum.RPC_SET_HAT }
func (d *RpcSetHat) WriteToPacket(packet *protocol.Packet) { packet.WriteString(d.HatID) }
func (d *RpcSetHat) ReadFromPacket(packet *protocol.Packet) { d.HatID = packet.ReadString() }
//
// 0x28 RpcSetSkin
//
type RpcSetSkin struct{ SkinID string }
func (d *RpcSetSkin) CallCode() byte { return enum.RPC_SET_SKIN }
func (d *RpcSetSkin) WriteToPacket(packet *protocol.Packet) { packet.WriteString(d.SkinID) }
func (d *RpcSetSkin) ReadFromPacket(packet *protocol.Packet) { d.SkinID = packet.ReadString() }
//
// 0x29 RpcSetPet
//
type RpcSetPet struct{ PetID string }
func (d *RpcSetPet) CallCode() byte { return enum.RPC_SET_PET }
func (d *RpcSetPet) WriteToPacket(packet *protocol.Packet) { packet.WriteString(d.PetID) }
func (d *RpcSetPet) ReadFromPacket(packet *protocol.Packet) { d.PetID = packet.ReadString() }
//
// 0x2c RpcSetRole
type RpcSetRole struct{ RoleType protocol.RoleTypes }
func (d *RpcSetRole) CallCode() byte { return enum.RPC_SET_ROLE }
func (d *RpcSetRole) WriteToPacket(packet *protocol.Packet) { packet.Write(byte(d.RoleType)) }
func (d *RpcSetRole) ReadFromPacket(packet *protocol.Packet) {
d.RoleType = protocol.RoleTypes(packet.Read())
}

View File

@ -0,0 +1,16 @@
package gamedata
import "tea.melonie54.xyz/sean/go-susapp/src/protocol"
type SetActivePodType struct {
PodType string
}
func (d *SetActivePodType) AsHazel() *protocol.Hazel {
var a protocol.HazelPayload = d
return protocol.NewHazelFromPayload(&a)
}
func (d *SetActivePodType) TypeCode() byte { return 0x15 }
func (d *SetActivePodType) Write(packet *protocol.Packet) { packet.WriteString(d.PodType) }
func (d *SetActivePodType) Read(packet *protocol.Packet) { d.PodType = packet.ReadString() }

View File

@ -5,9 +5,11 @@ go 1.17
replace ( replace (
tea.melonie54.xyz/sean/go-susapp/src/protocol => ../protocol tea.melonie54.xyz/sean/go-susapp/src/protocol => ../protocol
tea.melonie54.xyz/sean/go-susapp/src/util => ../util tea.melonie54.xyz/sean/go-susapp/src/util => ../util
tea.melonie54.xyz/sean/go-susapp/src/enum => ../enum
) )
require ( require (
tea.melonie54.xyz/sean/go-susapp/src/protocol v0.0.0 tea.melonie54.xyz/sean/go-susapp/src/protocol v0.0.0
tea.melonie54.xyz/sean/go-susapp/src/util v0.0.0 tea.melonie54.xyz/sean/go-susapp/src/util v0.0.0
tea.melonie54.xyz/sean/go-susapp/src/enum v0.0.0
) )

View File

@ -4,6 +4,7 @@ import "tea.melonie54.xyz/sean/go-susapp/src/protocol"
type JoinGameC2S struct { type JoinGameC2S struct {
GameID int32 GameID int32
Crossplay bool
} }
func (d *JoinGameC2S) TypeCode() byte { func (d *JoinGameC2S) TypeCode() byte {
@ -12,8 +13,10 @@ func (d *JoinGameC2S) TypeCode() byte {
func (d *JoinGameC2S) Write(packet *protocol.Packet) { func (d *JoinGameC2S) Write(packet *protocol.Packet) {
packet.WriteInt32(d.GameID) packet.WriteInt32(d.GameID)
packet.WriteBool(d.Crossplay)
} }
func (d *JoinGameC2S) Read(packet *protocol.Packet) { func (d *JoinGameC2S) Read(packet *protocol.Packet) {
d.GameID = packet.ReadInt32() d.GameID = packet.ReadInt32()
d.Crossplay = packet.ReadBool()
} }

View File

@ -23,16 +23,51 @@ type GameOptionsData struct {
VisualTasks bool VisualTasks bool
AnonymousVotes bool AnonymousVotes bool
TaskBarUpdates byte TaskBarUpdates byte
RoleOptions *RoleOptionsData
} }
var currentGameOptionsVersion byte = 4 var currentGameOptionsVersion byte = 5
// Create new default options // NewDefaultGameOptionsData Create new default options
func NewDefaultGameOptionsData() *GameOptionsData { func NewDefaultGameOptionsData() *GameOptionsData {
return &GameOptionsData{currentGameOptionsVersion, 10, 1, 1, 1, 1, 1.5, 45, 1, 1, 2, 1, 1, 1, 15, 120, true, 15, true, true, false, 0} return &GameOptionsData{
Version: currentGameOptionsVersion,
MaxNumberOfPlayers: 10,
Keywords: 1,
Maps: 1,
PlayerSpeedModifier: 1,
CrewmateLightModifier: 1,
ImpostorLightModifier: 1.5,
KillCooldown: 45,
NumberOfCommonTasks: 1,
NumberOfLongTasks: 1,
NumberOfShortTasks: 2,
NumberOfEmergencyMeetings: 1,
NumberOfImpostors: 1,
KillDistance: 1,
DiscussionTime: 15,
VotingTime: 120,
IsDefaults: true,
EmergencyCooldown: 15,
ConfirmEjects: true,
VisualTasks: true,
RoleOptions: &RoleOptionsData{
ShapeshifterLeaveSkin: false,
ShapeshifterCooldown: 10,
ShapeshifterDuration: 30,
ScientistCooldown: 15,
ScientistBatteryCharge: 5,
GuardianAngelCooldown: 60,
ImpostorsCanSeeProtect: false,
ProtectionDurationSeconds: 10,
EngineerCooldown: 30,
EngineerInVentMaxTime: 15,
RoleRates: make(map[RoleTypes]*RoleRate),
},
}
} }
// Create new options from packet data // NewGameOptionsDataFromPacket Create new options from packet data
func NewGameOptionsDataFromPacket(packet *Packet) *GameOptionsData { func NewGameOptionsDataFromPacket(packet *Packet) *GameOptionsData {
a := NewDefaultGameOptionsData() a := NewDefaultGameOptionsData()
a.Read(packet) a.Read(packet)
@ -63,6 +98,7 @@ func (data *GameOptionsData) Write(packet *Packet) {
p.WriteBool(data.VisualTasks) p.WriteBool(data.VisualTasks)
p.WriteBool(data.AnonymousVotes) p.WriteBool(data.AnonymousVotes)
p.Write(data.TaskBarUpdates) p.Write(data.TaskBarUpdates)
data.RoleOptions.Write(p)
packet.WritePackedUInt32(uint32(p.Size())) packet.WritePackedUInt32(uint32(p.Size()))
p.Copy(packet) p.Copy(packet)
} }
@ -93,4 +129,6 @@ func (data *GameOptionsData) Read(packet *Packet) {
data.VisualTasks = p.ReadBoolDefault(true) data.VisualTasks = p.ReadBoolDefault(true)
data.AnonymousVotes = p.ReadBoolDefault(false) data.AnonymousVotes = p.ReadBoolDefault(false)
data.TaskBarUpdates = p.ReadDefault(0) data.TaskBarUpdates = p.ReadDefault(0)
data.RoleOptions = &RoleOptionsData{}
data.RoleOptions.Read(p)
} }

View File

@ -5,9 +5,11 @@ go 1.17
replace ( replace (
tea.melonie54.xyz/sean/go-susapp/src/util => ../util tea.melonie54.xyz/sean/go-susapp/src/util => ../util
tea.melonie54.xyz/sean/go-susapp/src/version => ../version tea.melonie54.xyz/sean/go-susapp/src/version => ../version
tea.melonie54.xyz/sean/go-susapp/src/enum => ../enum
) )
require ( require (
tea.melonie54.xyz/sean/go-susapp/src/enum v0.0.0-20211217150321-0ba6d712d37d
tea.melonie54.xyz/sean/go-susapp/src/util v0.0.0 tea.melonie54.xyz/sean/go-susapp/src/util v0.0.0
tea.melonie54.xyz/sean/go-susapp/src/version v0.0.0 tea.melonie54.xyz/sean/go-susapp/src/version v0.0.0-20211217150321-0ba6d712d37d
) )

2
src/protocol/go.sum Normal file
View File

@ -0,0 +1,2 @@
tea.melonie54.xyz/sean/go-susapp/src/enum v0.0.0-20211217150321-0ba6d712d37d h1:JfR7qgdhTWjw7nZM4ITT/CfO3djE1p4/qAHtxiuhhxc=
tea.melonie54.xyz/sean/go-susapp/src/enum v0.0.0-20211217150321-0ba6d712d37d/go.mod h1:Jh+hf9VCNIGF2UbEh91R8ROF65KW1wLslRv2d+5iH1w=

View File

@ -153,7 +153,7 @@ func (packet *Packet) WriteBool(v bool) {
} }
} }
func (packet *Packet) ParsePackedInt32() int32 { func (packet *Packet) ReadPackedInt32() int32 {
return int32(packet.ReadPackedUInt32()) return int32(packet.ReadPackedUInt32())
} }

View File

@ -1,53 +1,63 @@
package protocol package protocol
import "tea.melonie54.xyz/sean/go-susapp/src/enum"
type PlayerData struct { type PlayerData struct {
PlayerID byte PlayerID byte
Name string Name string
ColorID uint32
HatID uint32
PetID uint32
SkinID uint32
Flags byte Flags byte
Tasks []*TaskInfo Tasks []*TaskInfo
Outfits map[enum.PlayerOutfitType]*PlayerOutfit
CurrentOutfitType enum.PlayerOutfitType
PlayerLevel uint32
Role RoleTypes
}
func (player *PlayerData) PlayerOutfit() *PlayerOutfit {
return player.Outfits[player.CurrentOutfitType]
} }
func (player *PlayerData) Write(packet *Packet) { func (player *PlayerData) Write(packet *Packet) {
packet.Write(player.PlayerID) packet.Write(player.PlayerID)
packet.WriteString(player.Name) packet.Write(byte(len(player.Outfits)))
packet.WritePackedUInt32(player.ColorID) for outfitType, outfit := range player.Outfits {
packet.WritePackedUInt32(player.HatID) packet.Write(byte(outfitType))
packet.WritePackedUInt32(player.PetID) outfit.Write(packet)
packet.WritePackedUInt32(player.SkinID) }
packet.WritePackedUInt32(player.PlayerLevel)
packet.Write(player.Flags) packet.Write(player.Flags)
packet.WriteUInt16(uint16(player.Role))
packet.Write(byte(len(player.Tasks))) packet.Write(byte(len(player.Tasks)))
for i := 0; i < len(player.Tasks); i++ { for i := 0; i < len(player.Tasks); i++ {
player.Tasks[i].Write(packet) player.Tasks[i].Write(packet)
} }
} }
func (player *PlayerData) Read(packet *Packet) { func (player *PlayerData) Read(packet *Packet) {
player.PlayerID = packet.Read() player.PlayerID = packet.Read()
player.Name = packet.ReadString() player.Outfits = make(map[enum.PlayerOutfitType]*PlayerOutfit)
player.ColorID = packet.ReadPackedUInt32() n := packet.Read()
player.HatID = packet.ReadPackedUInt32() for i := 0; i < int(n); i++ {
player.PetID = packet.ReadPackedUInt32() key := enum.PlayerOutfitType(packet.Read())
player.SkinID = packet.ReadPackedUInt32() player.Outfits[key] = &PlayerOutfit{}
player.Outfits[key].Read(packet)
}
player.PlayerLevel = packet.ReadPackedUInt32()
player.Flags = packet.Read() player.Flags = packet.Read()
player.Tasks = make([]*TaskInfo, packet.Read()) taskCount := packet.Read()
if taskCount != byte(len(player.Tasks)) {
player.Tasks = make([]*TaskInfo, taskCount)
for i := 0; i < len(player.Tasks); i++ { for i := 0; i < len(player.Tasks); i++ {
player.Tasks[i].Read(packet) player.Tasks[i].Read(packet)
} }
} }
type TaskInfo struct {
TaskID uint32
IsCompleted bool
} }
func (task *TaskInfo) Write(packet *Packet) { func (player *PlayerData) IsImpostor() bool {
packet.WritePackedUInt32(task.TaskID) return player.Role == enum.ROLE_TYPES_IMPOSTOR || player.Role == enum.ROLE_TYPES_SHAPESHIFTER
packet.WriteBool(task.IsCompleted)
} }
func (task *TaskInfo) Read(packet *Packet) {
task.TaskID = packet.ReadPackedUInt32() func (player *PlayerData) CanVent() bool {
task.IsCompleted = packet.ReadBool() return player.Role == enum.ROLE_TYPES_IMPOSTOR || player.Role == enum.ROLE_TYPES_ENGINEER
} }

View File

@ -0,0 +1,67 @@
package protocol
type PlayerOutfit struct {
Color int
HatId string
PetId string
SkinId string
VisorId string
NamePlateId string
PlayerName string
}
func NewPlayerOutfit() *PlayerOutfit {
return &PlayerOutfit{
Color: -1,
HatId: "missing",
PetId: "missing",
SkinId: "missing",
VisorId: "missing",
NamePlateId: "missing",
PlayerName: "",
}
}
func (outfit *PlayerOutfit) IsIncomplete() bool {
if outfit.PlayerName == "" {
return true
}
if outfit.Color == -1 {
return true
}
if outfit.HatId == "missing" {
return true
}
if outfit.PetId == "missing" {
return true
}
if outfit.SkinId == "missing" {
return true
}
if outfit.VisorId == "missing" {
return true
}
if outfit.NamePlateId == "missing" {
return true
}
return false
}
func (outfit *PlayerOutfit) Write(packet *Packet) {
packet.WriteString(outfit.PlayerName)
packet.WritePackedInt32(int32(outfit.Color))
packet.WriteString(outfit.HatId)
packet.WriteString(outfit.PetId)
packet.WriteString(outfit.SkinId)
packet.WriteString(outfit.VisorId)
packet.WriteString(outfit.NamePlateId)
}
func (outfit *PlayerOutfit) Read(packet *Packet) {
outfit.PlayerName = packet.ReadString()
outfit.Color = int(packet.ReadPackedInt32())
outfit.HatId = packet.ReadString()
outfit.PetId = packet.ReadString()
outfit.SkinId = packet.ReadString()
outfit.VisorId = packet.ReadString()
outfit.NamePlateId = packet.ReadString()
}

View File

@ -0,0 +1,66 @@
package protocol
type RoleTypes byte
type RoleRate struct {
MaxCount byte
Chance byte
}
type RoleOptionsData struct {
ShapeshifterLeaveSkin bool
ShapeshifterCooldown byte
ShapeshifterDuration byte
ScientistCooldown byte
ScientistBatteryCharge byte
GuardianAngelCooldown byte
ImpostorsCanSeeProtect bool
ProtectionDurationSeconds byte
EngineerCooldown byte
EngineerInVentMaxTime byte
RoleRates map[RoleTypes]*RoleRate
}
func (options *RoleOptionsData) Write(packet *Packet) {
packet.WritePackedInt32(int32(len(options.RoleRates)))
for k, v := range options.RoleRates {
packet.Write(byte(k))
packet.Write(v.MaxCount)
packet.Write(v.Chance)
}
packet.WriteBool(options.ShapeshifterLeaveSkin)
packet.Write(options.ShapeshifterCooldown)
packet.Write(options.ShapeshifterDuration)
packet.Write(options.ScientistCooldown)
packet.Write(options.GuardianAngelCooldown)
packet.Write(options.EngineerCooldown)
packet.Write(options.EngineerInVentMaxTime)
packet.Write(options.ScientistBatteryCharge)
packet.Write(options.ProtectionDurationSeconds)
packet.WriteBool(options.ImpostorsCanSeeProtect)
}
func (options *RoleOptionsData) Read(packet *Packet) {
options.RoleRates = make(map[RoleTypes]*RoleRate)
n := packet.ReadInt32()
for i := 0; i < int(n); i++ {
key := packet.ReadInt16()
val := &RoleRate{
MaxCount: packet.Read(),
Chance: packet.Read(),
}
options.RoleRates[RoleTypes(key)] = val
}
options.ShapeshifterLeaveSkin = packet.ReadBool()
options.ShapeshifterCooldown = packet.Read()
options.ShapeshifterDuration = packet.Read()
options.ScientistCooldown = packet.Read()
options.GuardianAngelCooldown = packet.Read()
options.EngineerCooldown = packet.Read()
options.EngineerInVentMaxTime = packet.Read()
options.ScientistBatteryCharge = packet.Read()
options.ProtectionDurationSeconds = packet.Read()
options.ImpostorsCanSeeProtect = packet.ReadBool()
}

15
src/protocol/taskinfo.go Normal file
View File

@ -0,0 +1,15 @@
package protocol
type TaskInfo struct {
TaskID uint32
IsCompleted bool
}
func (task *TaskInfo) Write(packet *Packet) {
packet.WritePackedUInt32(task.TaskID)
packet.WriteBool(task.IsCompleted)
}
func (task *TaskInfo) Read(packet *Packet) {
task.TaskID = packet.ReadPackedUInt32()
task.IsCompleted = packet.ReadBool()
}

View File

@ -68,9 +68,9 @@ type PlayerObject struct {
PlayerNetworkTransform uint32 PlayerNetworkTransform uint32
PlayerName string PlayerName string
PlayerColor byte PlayerColor byte
PlayerPet uint32 PlayerPet string
PlayerHat uint32 PlayerHat string
PlayerSkin uint32 PlayerSkin string
InVent bool InVent bool
IsImpostor bool IsImpostor bool
} }

8
sus.go
View File

@ -132,7 +132,9 @@ func (sus *SusApp) startApp() {
r := sus.renderer r := sus.renderer
da.Connect("draw", func(da *gtk.DrawingArea, cr *cairo.Context) { da.Connect("draw", func(da *gtk.DrawingArea, cr *cairo.Context) {
if r != nil && da != nil && cr != nil {
r.Draw(da, cr) r.Draw(da, cr)
}
}) })
da.AddEvents(int(gdk.KEY_RELEASE_MASK) | int(gdk.KEY_PRESS_MASK) | int(gdk.EVENT_CONFIGURE) | int(gdk.EVENT_BUTTON_PRESS)) da.AddEvents(int(gdk.KEY_RELEASE_MASK) | int(gdk.KEY_PRESS_MASK) | int(gdk.EVENT_CONFIGURE) | int(gdk.EVENT_BUTTON_PRESS))
@ -283,11 +285,11 @@ func (sus *SusApp) handlePingPacket(net *protocol.PacketHandler, nonce uint16) {
func (sus *SusApp) sendPetHatAndSkin(net *protocol.PacketHandler) { func (sus *SusApp) sendPetHatAndSkin(net *protocol.PacketHandler) {
// Send RPC SetPet, SetHat, SetSkin // Send RPC SetPet, SetHat, SetSkin
sus.state.CurrentGame.CheckPetHatAndSkinNonce = net.GetNonce() sus.state.CurrentGame.CheckPetHatAndSkinNonce = net.GetNonce()
var f1a gamedata.RpcSub = &gamedata.RpcSetPet{PetID: enum.PET_ELLIE_ROSE + 1} var f1a gamedata.RpcSub = &gamedata.RpcSetPet{PetID: "pet_Robot"}
var f2a packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(sus.state.CurrentGame.ClientPlayerNetID, &f1a) var f2a packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(sus.state.CurrentGame.ClientPlayerNetID, &f1a)
var f1b gamedata.RpcSub = &gamedata.RpcSetHat{HatID: enum.HAT_HEART_PIN + 1} var f1b gamedata.RpcSub = &gamedata.RpcSetHat{HatID: "hat_pk04_Bear"}
var f2b packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(sus.state.CurrentGame.ClientPlayerNetID, &f1b) var f2b packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(sus.state.CurrentGame.ClientPlayerNetID, &f1b)
var f1c gamedata.RpcSub = &gamedata.RpcSetSkin{SkinID: enum.SKIN_RIGHT_HAND_MAN_REBORN} var f1c gamedata.RpcSub = &gamedata.RpcSetSkin{SkinID: "skin_Winter"}
var f2c packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(sus.state.CurrentGame.ClientPlayerNetID, &f1c) var f2c packets.GameDataSubpacket = gamedata.NewRpcFromRpcSub(sus.state.CurrentGame.ClientPlayerNetID, &f1c)
var f3 protocol.HazelPayload = &packets.GameDataAll{GameID: sus.state.CurrentGame.GameID, Subpackets: []*protocol.Hazel{ var f3 protocol.HazelPayload = &packets.GameDataAll{GameID: sus.state.CurrentGame.GameID, Subpackets: []*protocol.Hazel{
f2a.AsHazel(), f2a.AsHazel(),