### Install retroproto Source: https://github.com/kralamoure/retroproto/blob/main/README.md Use 'go get' to install the retroproto library. ```sh go get github.com/kralamoure/retroproto ``` -------------------------------- ### Implement Authentication Flow in Go Source: https://context7.com/kralamoure/retroproto/llms.txt A complete example showing the handshake, version exchange, password encryption, and login success verification. ```go package main import ( "fmt" "strings" "github.com/kralamoure/retroproto" "github.com/kralamoure/retroproto/msgcli" "github.com/kralamoure/retroproto/msgsvr" ) func main() { // 1. Server sends HelloConnect with salt helloPacket := "HCfdbijergrfklvdnsdfgviojsidesokpm" id, _ := retroproto.MsgSvrIdByPkt(helloPacket) extra := strings.TrimPrefix(helloPacket, string(id)) hello := &msgsvr.AksHelloConnect{} hello.Deserialize(extra) fmt.Printf("Received salt: %s\n", hello.Salt) // 2. Client sends version version := msgcli.AccountVersion{ Major: 1, Minor: 29, Patch: 1, Beta: 0, Streaming: false, Electron: false, } versionExtra, _ := version.Serialized() fmt.Printf("Version packet: %s\n", versionExtra) // Output: 1.29.1 // 3. Client encrypts password and sends credentials password := "mypassword" encrypted := retroproto.EncryptPassword(password, hello.Salt) creds := msgcli.AccountCredential{ Username: "player123", Hash: encrypted, CryptoMethod: 1, } credsExtra, _ := creds.Serialized() fmt.Printf("Credentials: %s\n", credsExtra) // 4. Server responds with success or error successPacket := "AlK1" id, _ = retroproto.MsgSvrIdByPkt(successPacket) extra = strings.TrimPrefix(successPacket, string(id)) loginSuccess := &msgsvr.AccountLoginSuccess{} loginSuccess.Deserialize(extra) fmt.Printf("Login authorized: %v\n", loginSuccess.Authorized) // Output: Login authorized: true } ``` -------------------------------- ### EncryptPassword Utility Source: https://context7.com/kralamoure/retroproto/llms.txt Provides an example of encrypting a password using the protocol's custom encryption algorithm. ```go package main import ( "fmt" "github.com/kralamoure/retroproto" ) func main() { password := "mySecretPassword" salt := "fdbijergrfklvdnsdfgviojsidesokpm" // Encrypt password for authentication encrypted := retroproto.EncryptPassword(password, salt) fmt.Printf("Encrypted password: %s\n", encrypted) // Output: Encrypted password: (32-character encrypted string) // The encryption uses a custom algorithm: // - Iterates through each character of the password // - Uses corresponding salt character for transformation // - Produces 2 characters output per input character // Result length = password length * 2 } ``` -------------------------------- ### Serialize a Dofus Retro Client Message Source: https://github.com/kralamoure/retroproto/blob/main/README.md This example demonstrates serializing a client message struct into a network packet string. Note that certain message types might not require their protocol ID to be prepended. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/msgcli" ) func main() { message := msgcli.AccountAddCharacter{ Name: "XxRamboPLxX", Class: 1, Sex: 0, Color1: "3778e0", Color2: "0d0d0d", Color3: "f4f4f5", } extra, _ := message.Serialized() // Note: packets for msgcli.AccountVersion and msgcli.AccountCredential should not include their protocol ID packet := fmt.Sprintf("%s%s", message.ProtocolId(), extra) fmt.Print(packet) // "AAXxRamboPLxX|1|0|3635424|855309|16053493" } ``` -------------------------------- ### AccountCredential Message Handling Source: https://context7.com/kralamoure/retroproto/llms.txt Demonstrates creating and serializing login credentials, as well as encrypting a password using a server-provided salt. ```go package main import ( "fmt" "github.com/kralamoure/retroproto" "github.com/kralamoure/retroproto/msgcli" ) func main() { // Create login credentials message message := msgcli.AccountCredential{ Username: "player123", Hash: "encryptedPasswordHash", CryptoMethod: 1, // Encryption method used } // Serialize for sending extra, err := message.Serialized() if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println(extra) // Output: player123\n#1encryptedPasswordHash // Encrypt password using the provided salt salt := "fdbijergrfklvdnsdfgviojsidesokpm" password := "mypassword" encryptedPwd := retroproto.EncryptPassword(password, salt) fmt.Printf("Encrypted: %s\n", encryptedPwd) } ``` -------------------------------- ### AksHelloConnect Message Handling Source: https://context7.com/kralamoure/retroproto/llms.txt Shows how to create, serialize, and deserialize the server hello message containing the authentication salt. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/msgsvr" ) func main() { // Create server hello message with authentication salt message := msgsvr.AksHelloConnect{ Salt: "fdbijergrfklvdnsdfgviojsidesokpm", } // Serialize for sending to client extra, err := message.Serialized() if err != nil { fmt.Printf("Error: %v\n", err) return } // Full packet with protocol ID packet := fmt.Sprintf("%s%s", message.MessageId(), extra) fmt.Println(packet) // Output: HCfdbijergrfklvdnsdfgviojsidesokpm // Deserialize from received packet received := &msgsvr.AksHelloConnect{} received.Deserialize("randomsaltstring123456789") fmt.Printf("Salt: %s\n", received.Salt) // Output: Salt: randomsaltstring123456789 } ``` -------------------------------- ### AccountLoginSuccess Message Handling Source: https://context7.com/kralamoure/retroproto/llms.txt Shows how to create, serialize, and deserialize a successful login response. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/msgsvr" ) func main() { // Create login success response message := msgsvr.AccountLoginSuccess{ Authorized: true, // Admin/moderator status } // Serialize for sending extra, _ := message.Serialized() packet := fmt.Sprintf("%s%s", message.MessageId(), extra) fmt.Println(packet) // Output: AlK1 // Deserialize incoming message received := &msgsvr.AccountLoginSuccess{} received.Deserialize("1") fmt.Printf("Authorized: %v\n", received.Authorized) // Output: Authorized: true } ``` -------------------------------- ### Create and Serialize Character Messages Source: https://context7.com/kralamoure/retroproto/llms.txt Demonstrates how to instantiate a message struct, serialize it for network transmission, and deserialize raw data back into the struct. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/msgcli" ) func main() { // Create a new character creation message message := msgcli.AccountAddCharacter{ Name: "XxRamboPLxX", Class: 1, // Character class ID Sex: 0, // 0 = male, 1 = female Color1: "3778e0", // Hair color (hex) Color2: "0d0d0d", // Primary color (hex) Color3: "f4f4f5", // Secondary color (hex) } // Serialize the message for sending extra, err := message.Serialized() if err != nil { fmt.Printf("Error: %v\n", err) return } // Combine with protocol ID for full packet // Note: Most messages include their protocol ID packet := fmt.Sprintf("%s%s", message.MessageId(), extra) fmt.Println(packet) // Output: AA|XxRamboPLxX|1|0|3635424|855309|16053493 // Deserialize from raw extra data received := &msgcli.AccountAddCharacter{} received.Deserialize("XxRamboPLxX|1|0|3635424|855309|16053493") fmt.Printf("Name: %s, Class: %d\n", received.Name, received.Class) // Output: Name: XxRamboPLxX, Class: 1 } ``` -------------------------------- ### Manage Character Accessories in Go Source: https://context7.com/kralamoure/retroproto/llms.txt Demonstrates how to initialize, serialize, and deserialize character accessory data using the typ.CommonAccessories struct. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/typ" ) func main() { // Create accessories data accessories := typ.CommonAccessories{ Weapon: typ.CommonAccessoriesAccessory{ TemplateId: 1234, Type: 0, Frame: 0, }, Hat: typ.CommonAccessoriesAccessory{ TemplateId: 5678, }, Cape: typ.CommonAccessoriesAccessory{ TemplateId: 9012, }, Pet: typ.CommonAccessoriesAccessory{}, Shield: typ.CommonAccessoriesAccessory{ TemplateId: 3456, }, } // Serialize to protocol format serialized, _ := accessories.Serialized() fmt.Println(serialized) // Output: 4d2,162e,2334,,d80 // Deserialize from packet data received := &typ.CommonAccessories{} received.Deserialize("4d2,162e,2334,,d80") fmt.Printf("Weapon ID: %d\n", received.Weapon.TemplateId) // Output: Weapon ID: 1234 } ``` -------------------------------- ### Implement Message Client Template in Go Source: https://github.com/kralamoure/retroproto/blob/main/assets/template.msgcli.txt Use this template to define new message client types. Ensure the placeholder {{ . }} is replaced with the specific message name. ```go // generated (unrevised) package msgcli import ( "github.com/kralamoure/retroproto" ) type {{ . }} struct{} func (m {{ . }}) ProtocolId() retroproto.MsgCliId { return retroproto.{{ . }} } func (m {{ . }}) MessageName() string { return "{{ . }}" } func (m {{ . }}) Serialized() (string, error) { return "", retroproto.ErrNotImplemented } func (m *{{ . }}) Deserialize(extra string) error { return retroproto.ErrNotImplemented } ``` -------------------------------- ### AccountLoginError Message Handling Source: https://context7.com/kralamoure/retroproto/llms.txt Demonstrates handling login failure responses and lists available error reason codes. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/enum" "github.com/kralamoure/retroproto/msgsvr" ) func main() { // Create login error response message := msgsvr.AccountLoginError{ Reason: enum.AccountLoginErrorReason.Banned, Extra: "2024-12-31", // Ban expiration date } // Serialize for sending extra, _ := message.Serialized() packet := fmt.Sprintf("%s%s", message.MessageId(), extra) fmt.Println(packet) // Output: AlEb2024-12-31 // All available error reasons: fmt.Printf("BadVersion: %c\n", enum.AccountLoginErrorReason.BadVersion) // 'v' fmt.Printf("Banned: %c\n", enum.AccountLoginErrorReason.Banned) // 'b' fmt.Printf("AlreadyLogged: %c\n", enum.AccountLoginErrorReason.AlreadyLogged) // 'a' fmt.Printf("ServerFull: %c\n", enum.AccountLoginErrorReason.ServerFull) // 'w' fmt.Printf("Kicked: %c\n", enum.AccountLoginErrorReason.Kicked) // 'k' fmt.Printf("AccessDenied: %c\n", enum.AccountLoginErrorReason.AccessDenied) // 'f' } ``` -------------------------------- ### Define Message Server Structure Source: https://github.com/kralamoure/retroproto/blob/main/assets/template.msgsvr.txt Use this template to define new message server types. Ensure the placeholder {{ . }} is replaced with the specific message name. ```go package msgsvr import ( "github.com/kralamoure/retroproto" ) type {{ . }} struct{} func (m {{ . }}) ProtocolId() retroproto.MsgSvrId { return retroproto.{{ . }} } func (m {{ . }}) MessageName() string { return "{{ . }}" } func (m {{ . }}) Serialized() (string, error) { return "", retroproto.ErrNotImplemented } func (m *{{ . }}) Deserialize(extra string) error { return retroproto.ErrNotImplemented } ``` -------------------------------- ### Custom Base64-like Encoding and Decoding Source: https://context7.com/kralamoure/retroproto/llms.txt Utilize Encode64 and Decode64 for custom base64-like encoding and decoding of numbers (0-63) to characters and vice-versa. The library uses a specific zipKey for these operations. ```go package main import ( "fmt" "github.com/kralamoure/retroproto" ) func main() { // Encode a number (0-63) to a character encoded, err := retroproto.Encode64(42) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("Encoded 42: %c\n", encoded) // Output: Encoded 42: Q // Decode a character back to number decoded, err := retroproto.Decode64('Q') if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("Decoded 'Q': %d\n", decoded) // Output: Decoded 'Q': 42 // The zipKey used is: // "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" } ``` -------------------------------- ### Identify and Deserialize Server Messages Source: https://context7.com/kralamoure/retroproto/llms.txt Use MsgSvrIdByPkt to parse outgoing server packets or analyze server responses. ```go package main import ( "fmt" "strings" "github.com/kralamoure/retroproto" "github.com/kralamoure/retroproto/msgsvr" ) func main() { packet := "HCfdbijergrfklvdnsdfgviojsidesokpm" // Identify message type from packet id, ok := retroproto.MsgSvrIdByPkt(packet) if !ok { fmt.Println("Unknown message") return } // id = "HC" (AksHelloConnect) // Extract the extra data after the message ID extra := strings.TrimPrefix(packet, string(id)) // extra = "fdbijergrfklvdnsdfgviojsidesokpm" // Deserialize based on message type switch id { case retroproto.AksHelloConnect: message := &msgsvr.AksHelloConnect{} if err := message.Deserialize(extra); err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("%+v\n", *message) // Output: {Salt:fdbijergrfklvdnsdfgviojsidesokpm} } } ``` -------------------------------- ### Serialize a Dofus Retro Server Message Source: https://github.com/kralamoure/retroproto/blob/main/README.md Illustrates serializing a server message struct into a packet string. The ProtocolId() method is used to prepend the message identifier. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/msgsvr" ) func main() { message := msgsvr.AksHelloConnect{Salt: "fdbijergrfklvdnsdfgviojsidesokpm"} extra, _ := message.Serialized() packet := fmt.Sprintf("%s%s", message.ProtocolId(), extra) fmt.Print(packet) // "HCfdbijergrfklvdnsdfgviojsidesokpm" } ``` -------------------------------- ### AccountAddCharacter - Create New Character Source: https://context7.com/kralamoure/retroproto/llms.txt Client message structure for creating a new character, including name, class, sex, and appearance colors. ```APIDOC ## AccountAddCharacter ### Description Client message for creating a new character with name, class, sex, and appearance colors. ### Parameters #### Request Body - **Name** (string) - Required - Character name - **Class** (int) - Required - Character class ID - **Sex** (int) - Required - 0 for male, 1 for female - **Color1** (string) - Required - Hair color (hex) - **Color2** (string) - Required - Primary color (hex) - **Color3** (string) - Required - Secondary color (hex) ### Response - **Serialized** (string) - The serialized message string ready for transmission. ``` -------------------------------- ### Handle Game Entity Movement with GameMovement Source: https://context7.com/kralamoure/retroproto/llms.txt Utilize the GameMovement message type from msgsvr to handle sprite movement and entity data for characters, monsters, and NPCs. This message supports both serialization for sending and deserialization of incoming data. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/enum" "github.com/kralamoure/retroproto/msgsvr" ) func main() { // Create a character movement message message := msgsvr.GameMovement{ Sprites: []msgsvr.GameMovementSprite{ { Transition: false, Fight: false, Type: enum.GameMovementSpriteType.Default, // Character type Id: 12345, CellId: 256, Direction: 3, Character: msgsvr.GameMovementCharacter{ Name: "PlayerOne", GFXId: 10, Sex: 0, ScaleX: 100, ScaleY: 100, Level: 150, Color1: "3778e0", Color2: "0d0d0d", Color3: "f4f4f5", AlignmentId: 1, AlignmentLevel: 50, Grade: 5, Aura: 0, GuildName: "MyGuild", }, }, }, } // Serialize for sending extra, err := message.Serialized() if err != nil { fmt.Printf("Error: %v\n", err) return } packet := fmt.Sprintf("%s%s", message.MessageId(), extra) fmt.Println("Packet:", packet) // Deserialize incoming movement data received := &msgsvr.GameMovement{} err = received.Deserialize("|+256;3;0;12345;PlayerOne;0;10^100;0;1,50,5,12495;3778e0;0d0d0d;f4f4f5;,,,,,;0;;;MyGuild;;0000000000;") if err != nil { fmt.Printf("Error: %v\n", err) return } for _, sprite := range received.Sprites { fmt.Printf("Character: %s at cell %d\n", sprite.Character.Name, sprite.CellId) } } ``` -------------------------------- ### Identify and Deserialize Client Messages Source: https://context7.com/kralamoure/retroproto/llms.txt Use MsgCliIdByPkt to determine the message type from a raw packet string, then deserialize the payload into a specific struct. ```go package main import ( "fmt" "strings" "github.com/kralamoure/retroproto" "github.com/kralamoure/retroproto/msgcli" ) func main() { packet := "AAXxRamboPLxX|1|0|3635424|855309|16053493" // Identify message type from packet id, ok := retroproto.MsgCliIdByPkt(packet) if !ok { fmt.Println("Unknown message") return } // id = "AA" (AccountAddCharacter) // Extract the extra data after the message ID extra := strings.TrimPrefix(packet, string(id)) // extra = "XxRamboPLxX|1|0|3635424|855309|16053493" // Deserialize based on message type switch id { case retroproto.AccountAddCharacter: message := &msgcli.AccountAddCharacter{} if err := message.Deserialize(extra); err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("%+v\n", *message) // Output: {Name:XxRamboPLxX Class:1 Sex:0 Color1:3778e0 Color2:0d0d0d Color3:f4f4f5} } } ``` -------------------------------- ### Retrieve Message Names by ID in Go Source: https://context7.com/kralamoure/retroproto/llms.txt Use these functions to map protocol message IDs to human-readable names for debugging or logging purposes. ```go package main import ( "fmt" "github.com/kralamoure/retroproto" ) func main() { // Get client message name name, ok := retroproto.MsgCliNameByID(retroproto.AccountAddCharacter) fmt.Printf("AA = %s (found: %v)\n", name, ok) // Output: AA = AccountAddCharacter (found: true) // Get server message name svrName, ok := retroproto.MsgSvrNameByID(retroproto.AksHelloConnect) fmt.Printf("HC = %s (found: %v)\n", svrName, ok) // Output: HC = AksHelloConnect (found: true) // Unknown message returns "Unknown" unknown, ok := retroproto.MsgCliNameByID("ZZ") fmt.Printf("ZZ = %s (found: %v)\n", unknown, ok) // Output: ZZ = Unknown (found: false) } ``` -------------------------------- ### Decode Server Connection Info with SplitEncodedHostPortTicket Source: https://context7.com/kralamoure/retroproto/llms.txt Use SplitEncodedHostPortTicket to decode an encrypted server connection string containing host IP, port, and authentication ticket. Ensure the input string is correctly formatted. ```go package main import ( "fmt" "github.com/kralamoure/retroproto" ) func main() { // Encoded server connection data from AccountSelectServerSuccess encoded := "02486593BChticketstring123" host, port, ticket, err := retroproto.SplitEncodedHostPortTicket(encoded) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Printf("Host: %s\n", host) // Game server IP fmt.Printf("Port: %d\n", port) // Game server port fmt.Printf("Ticket: %s\n", ticket) // Authentication ticket } ``` -------------------------------- ### Deserialize a Dofus Retro Client Message Source: https://github.com/kralamoure/retroproto/blob/main/README.md Demonstrates deserializing a client message packet into its corresponding struct. Ensure the correct message ID is used for parsing. ```go package main import ( "fmt" "strings" "github.com/kralamoure/retroproto" "github.com/kralamoure/retroproto/msgcli" ) func main() { packet := "AAXxRamboPLxX|1|0|3635424|855309|16053493" id, _ := retroproto.MsgCliIdByPkt(packet) // "AA" extra := strings.TrimPrefix(packet, string(id)) // "XxRamboPLxX|1|0|3635424|855309|16053493" switch id { case retroproto.AccountAddCharacter: message := &msgcli.AccountAddCharacter{} message.Deserialize(extra) fmt.Printf("%+v", *message) // {Name:XxRamboPLxX Class:1 Sex:0 Color1:3778e0 Color2:0d0d0d Color3:f4f4f5} } } ``` -------------------------------- ### Send Chat Messages with ChatSend Source: https://context7.com/kralamoure/retroproto/llms.txt Use the ChatSend message type from msgcli to send chat messages to different channels, including general and private messages. Ensure the ChatChannel and PrivateReceiver fields are set appropriately. ```go package main import ( "fmt" "github.com/kralamoure/retroproto/msgcli" ) func main() { // Send a general chat message message := msgcli.ChatSend{ ChatChannel: '*', // General channel Message: "Hello everyone!", PrivateReceiver: "", Params: "", } extra, _ := message.Serialized() packet := fmt.Sprintf("%s%s", message.MessageId(), extra) fmt.Println(packet) // Output: BM*|Hello everyone!| // Send a private message privateMsg := msgcli.ChatSend{ ChatChannel: '@', // Private channel indicator PrivateReceiver: "PlayerName", Message: "Hey, want to trade?", Params: "", } extra2, _ := privateMsg.Serialized() fmt.Println(extra2) // Output: PlayerName|Hey, want to trade?| } ``` -------------------------------- ### MsgCliIdByPkt - Identify Client Message Source: https://context7.com/kralamoure/retroproto/llms.txt Parses a raw packet string to identify the corresponding client message ID for processing incoming client packets. ```APIDOC ## MsgCliIdByPkt ### Description Parses a raw packet string and returns the corresponding client message ID. This is the primary entry point for processing incoming client packets. ### Parameters #### Request Body - **packet** (string) - Required - The raw packet string received from the client. ### Response - **id** (string) - The identified message ID. - **ok** (boolean) - Status indicating if the message ID was successfully identified. ``` -------------------------------- ### Deserialize a Dofus Retro Server Message Source: https://github.com/kralamoure/retroproto/blob/main/README.md Shows how to deserialize a server message packet. The function MsgSvrIdByPkt is used to identify the message type before deserialization. ```go package main import ( "fmt" "strings" "github.com/kralamoure/retroproto" "github.com/kralamoure/retroproto/msgsvr" ) func main() { packet := "HCfdbijergrfklvdnsdfgviojsidesokpm" id, _ := retroproto.MsgSvrIdByPkt(packet) // "HC" extra := strings.TrimPrefix(packet, string(id)) // "fdbijergrfklvdnsdfgviojsidesokpm" switch id { case retroproto.AksHelloConnect: message := &msgsvr.AksHelloConnect{} message.Deserialize(extra) fmt.Printf("%+v", *message) // {Salt:fdbijergrfklvdnsdfgviojsidesokpm} } } ``` -------------------------------- ### MsgSvrIdByPkt - Identify Server Message Source: https://context7.com/kralamoure/retroproto/llms.txt Parses a raw packet string to identify the corresponding server message ID for processing outgoing server packets. ```APIDOC ## MsgSvrIdByPkt ### Description Parses a raw packet string and returns the corresponding server message ID. Used for processing outgoing server packets or analyzing server responses. ### Parameters #### Request Body - **packet** (string) - Required - The raw packet string received from the server. ### Response - **id** (string) - The identified message ID. - **ok** (boolean) - Status indicating if the message ID was successfully identified. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.