├── .idea ├── .gitignore ├── inspectionProfiles │ └── profiles_settings.xml └── misc.xml ├── README.md ├── client.go ├── config.go ├── connection.go ├── datagram_builder.go ├── default_handlers.go ├── host.go ├── info └── info.go ├── logger.go ├── minecraft_batch_packet.go ├── packet_handler.go ├── packets ├── add_entity_packet.go ├── add_player_packet.go ├── interact_packet.go ├── inventory_transaction_packet.go ├── inventoryio │ ├── inventory_action_io.go │ ├── inventory_action_io_list.go │ └── stream │ │ └── inventory_action_stream.go ├── modal_form_request_packet.go ├── modal_form_response_packet.go ├── move_entity_packet.go ├── move_player_packet.go ├── remove_entity_packet.go ├── set_game_mode_packet.go ├── set_title_packet.go ├── text_packet.go └── update_attributes_packet.go ├── proxy.go ├── reliability.go ├── server.go ├── server_data.go └── start └── main.go /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GoProxy (broken and outdated) 2 | 3 | ### GoProxy is a man-in-the-middle (MITM) proxy, it works by intercepting and modifying packets between the client and the server. 4 | 5 | ### How to use 6 | 7 | To use you must have Go version 1.9 or greater installed. 8 | 9 | 1. clone the project: `go get github.com/InfinityGamers/GoProxy` 10 | 2. navigate to the clone directory 11 | 3. install dependencies with `go install` 12 | 4. compile it and run it 13 | # Example use cases 14 | ### In this case it was mainly used to have advantages in Minecraft. 15 | 16 | ## KILLAURA CHEATS 17 | [![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/w4J-HzICmWc/0.jpg)](https://www.youtube.com/watch?v=w4J-HzICmWc) 18 | ## SPEED/KILLAURA/FLYING CHEATS 19 | [![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/h43zbAWX7zQ/0.jpg)](https://www.youtube.com/watch?v=h43zbAWX7zQ) 20 | ## AUTOMATED MINECRAFT PVP BOT 21 | [![IMAGE ALT TEXT HERE](https://img.youtube.com/vi/2NqTOBOu0-Y/0.jpg)](https://www.youtube.com/watch?v=2NqTOBOu0-Y) 22 | 23 | ### Notices 24 | 25 | This will not work on encrypted servers such as LBSG, Mineplex, etc.

26 | At the moment it has very simple features, but I will continue on updating as much as I can.
-------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "net" 5 | "github.com/infinitygamers/goproxy/packets" 6 | "github.com/google/uuid" 7 | packets2 "github.com/Irmine/GoMine/net/packets" 8 | "time" 9 | "github.com/golang/geo/r3" 10 | ) 11 | 12 | type Client struct { 13 | Host // Server extends a host that has writable packets 14 | // Server's udp address 15 | addr net.UDPAddr 16 | // the main Proxy 17 | Proxy *Proxy 18 | // the Connection between the Server 19 | // and the Client 20 | Conn *Connection 21 | // a bool that is true if the Client 22 | // is connected with the Server/Proxy 23 | Connection bool 24 | // the UUID of the Client's player 25 | uuid uuid.UUID 26 | // the entity runtime id of 27 | // the Client's player 28 | //entityRuntimeID uint64 29 | // the Client's position in the level 30 | Position r3.Vector 31 | } 32 | 33 | // returns new Client host 34 | // that has writable packets 35 | func NewClient(proxy *Proxy, conn *Connection) *Client { 36 | client := Client{} 37 | client.Proxy = proxy 38 | client.Conn = conn 39 | client.Connection = false 40 | return &client 41 | } 42 | 43 | // returns if this host is the client 44 | // this is the client struct to it returns true 45 | func (client Client) IsClient() bool { 46 | return true 47 | } 48 | 49 | // returns if this host is the client 50 | // this is the client struct to it returns false 51 | func (client Client) IsServer() bool { 52 | return false 53 | } 54 | 55 | // this function is from the host interface 56 | // it writes a packet buffer to the Client 57 | func (client Client) WritePacket(buffer []byte) { 58 | _, err := client.Proxy.UDPConn.WriteTo(buffer, &client.addr) 59 | if err != nil { 60 | Alert(err.Error()) 61 | } 62 | } 63 | 64 | // this function is from the host interface 65 | // This sends a single packet 66 | func (client Client) SendPacket(packet packets2.IPacket) { 67 | client.SendBatchPacket([]packets2.IPacket{packet}) 68 | } 69 | 70 | // this function is from the host interface 71 | // it sends a batch packet: 72 | // a packet with multiple packets inside 73 | func (client Client) SendBatchPacket(packets []packets2.IPacket) { 74 | datagram := client.Conn.pkHandler.DatagramBuilder.BuildFromPackets(packets) 75 | client.WritePacket(datagram.Buffer) 76 | } 77 | 78 | // this set's the udp address 79 | // which is used to communicate with the Client 80 | func (client *Client) SetAddress(addr net.UDPAddr) { 81 | client.addr = addr 82 | } 83 | 84 | // returns the Client's address as net.UDPAddr 85 | func (client Client) GetAddress() net.UDPAddr { 86 | return client.addr 87 | } 88 | 89 | // set true if the Client is connected with the 90 | // Server/Proxy 91 | func (client *Client) SetConnected(b bool) { 92 | client.Connection = b 93 | } 94 | 95 | // returns true if the Client is connected with the 96 | // Server/Proxy 97 | func (client *Client) IsConnected() bool { 98 | return client.Connection 99 | } 100 | 101 | // sends the Client's player a string message 102 | func (client *Client) SendMessage(m string) { 103 | text := packets.NewTextPacket() 104 | text.Message = m 105 | client.SendPacket(text) 106 | } 107 | 108 | // changes the Client's player game mode 109 | // although it updates for the Client, it will 110 | // not on the Server's side 111 | func (client *Client) SetGameMode(g int32) { 112 | gm := packets.NewSetGamemodePacket() 113 | gm.GameMode = g 114 | client.Conn.Server.SendPacket(gm) 115 | client.SendPacket(gm) 116 | } 117 | 118 | // Set a screen title and subtitle to the Client 119 | func (client *Client) SetTitle(title, subtitle string, fadeInTime, stayTime, fadeOutTime int32) { 120 | // title 121 | t := packets.NewSetTitlePacket() 122 | t.TitleType = packets.SetTitle 123 | t.Text = title 124 | t.FadeInTime = fadeInTime 125 | t.StayTime = stayTime 126 | t.FadeOutTime = fadeOutTime 127 | 128 | // subtitle 129 | t2 := packets.NewSetTitlePacket() 130 | t2.TitleType = packets.SetSubtitle 131 | t2.Text = subtitle 132 | t2.FadeInTime = fadeInTime 133 | t2.StayTime = stayTime 134 | t2.FadeOutTime = fadeOutTime 135 | 136 | client.SendBatchPacket([]packets2.IPacket{t, t2}) 137 | } 138 | 139 | func (client *Client) SendJoinMessage() { 140 | go func() { 141 | time.Sleep(5 * time.Second) 142 | client.SendMessage(BrightBlue + "==============================") 143 | client.SendMessage(BrightGreen + Prefix + Orange + "You are using " + Author + "'s Proxy version " + Version) 144 | client.SendMessage(BrightBlue + "==============================") 145 | client.SetTitle(BrightGreen + Author + "'s Proxy", Orange + Author + "'s Proxy version " + Version, 1, 1, 1) 146 | }() 147 | } -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "os" 5 | "gopkg.in/yaml.v2" 6 | "io/ioutil" 7 | ) 8 | 9 | type Config struct { 10 | 11 | ServerAddr string `yaml:"Server-address"` 12 | ServerPort int `yaml:"Server-port"` 13 | BindAddr string `yaml:"bind-address"` 14 | BindPort int `yaml:"bind-port"` 15 | 16 | } 17 | 18 | func NewConfig() Config { 19 | 20 | if _, err := os.Stat("./config.yml"); os.IsNotExist(err) { 21 | o, _ := yaml.Marshal(Config{ 22 | ServerAddr: "0.0.0.0", 23 | ServerPort: 19132, 24 | BindAddr: "0.0.0.0", 25 | BindPort: 19133, 26 | 27 | }) 28 | f, err := os.OpenFile("./config.yml", os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0644) 29 | if err != nil { 30 | panic(err) 31 | } 32 | _, err = f.WriteString(string(o)) 33 | if err != nil { 34 | panic(err) 35 | } 36 | f.Close() 37 | } 38 | 39 | var config Config 40 | yaml2, _ := ioutil.ReadFile("./config.yml") 41 | yaml.Unmarshal(yaml2, &config) 42 | 43 | return config 44 | } 45 | -------------------------------------------------------------------------------- /connection.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "net" 5 | "github.com/Irmine/GoRakLib/protocol" 6 | ) 7 | 8 | const ( 9 | IdUnconnectedPingOpenConnection = 0x01 //Client to Server 10 | IdUnconnectedPongOpenConnection = 0x1c //Server to Client as response to IdConnectedPingOpenConnection (0x01) 11 | IdOpenConnectionRequest1 = 0x05 //Client to Server 12 | IdOpenConnectionReply1 = 0x06 //Server to Client 13 | IdOpenConnectionRequest2 = 0x07 //Client to Server 14 | IdOpenConnectionReply2 = 0x08 //Server to Client 15 | ) 16 | 17 | type Connection struct { 18 | Proxy *Proxy 19 | Client *Client 20 | Server *Server 21 | pkHandler *PacketHandler 22 | } 23 | 24 | func NewConnection(proxy *Proxy) Connection { 25 | conn := Connection{} 26 | conn.Proxy = proxy 27 | 28 | conn.Client = NewClient(proxy, &conn) 29 | conn.Server = NewServer(proxy, &conn) 30 | conn.pkHandler = NewPacketHandler() 31 | 32 | conn.pkHandler.Conn = &conn 33 | 34 | RegisterDefaultHandlers(conn.pkHandler) 35 | 36 | return conn 37 | } 38 | 39 | func (conn *Connection) GetClient() *Client { 40 | return conn.Client 41 | } 42 | 43 | func (conn *Connection) GetServer() *Server { 44 | return conn.Server 45 | } 46 | 47 | func (conn *Connection) GetPacketHandler() *PacketHandler { 48 | return conn.pkHandler 49 | } 50 | 51 | func (conn *Connection) IsClient(addr net.UDPAddr) bool { 52 | return conn.Client.addr.IP.Equal(addr.IP) 53 | } 54 | 55 | func (conn *Connection) IsServer(addr net.UDPAddr) bool { 56 | return conn.Server.GetAddress().IP.Equal(addr.IP) 57 | } 58 | 59 | func (conn *Connection) handleUnconnectedPing(addr net.UDPAddr, buffer []byte) { 60 | conn.Client.SetAddress(addr) 61 | conn.Server.WritePacket(buffer) 62 | 63 | //stringAddr := addr.IP.String() 64 | //Info("Received unconnected ping from Client address: " + stringAddr) 65 | } 66 | 67 | func (conn *Connection) handleUnconnectedPong(addr net.UDPAddr, buffer []byte) { 68 | pk := protocol.NewUnconnectedPong() 69 | pk.SetBuffer(buffer) 70 | pk.Decode() 71 | pk.Encode() 72 | 73 | conn.Client.WritePacket(pk.Buffer) 74 | conn.Server.Data.ParseFromString(pk.PongData) 75 | 76 | //stringAddr := addr.IP.String() 77 | //Info("Received unconnected pong from Server address: " + stringAddr) 78 | } 79 | 80 | func (conn *Connection) handleConnectionRequest1(addr net.UDPAddr, buffer []byte) { 81 | conn.Client.SetAddress(addr) 82 | conn.Server.WritePacket(buffer) 83 | 84 | //stringAddr := addr.IP.String() 85 | // 86 | //Info("Received Connection request 1 from Client address: " + stringAddr) 87 | } 88 | 89 | func (conn *Connection) handleConnectionReply1(addr net.UDPAddr, buffer []byte) { 90 | //stringAddr := addr.IP.String() 91 | //Info("Received Connection reply 1 from Server address: " + stringAddr) 92 | 93 | pk := protocol.NewOpenConnectionReply1() 94 | pk.SetBuffer(buffer) 95 | pk.Decode() 96 | pk.Encode() 97 | 98 | conn.Client.WritePacket(pk.Buffer) 99 | } 100 | 101 | func (conn *Connection) handleConnectionRequest2(addr net.UDPAddr, buffer []byte) { 102 | conn.Client.SetAddress(addr) 103 | conn.Server.WritePacket(buffer) 104 | 105 | //stringAddr := addr.IP.String() 106 | // 107 | //Info("Received Connection request 2 from Client address: " + stringAddr) 108 | } 109 | 110 | func (conn *Connection) handleConnectionReply2(addr net.UDPAddr, buffer []byte) { 111 | conn.Client.SetConnected(true) 112 | 113 | //stringAddr := addr.IP.String() 114 | //Info("Received Connection reply 2 from Server address: " + stringAddr) 115 | 116 | pk := protocol.NewOpenConnectionReply2() 117 | pk.SetBuffer(buffer) 118 | pk.Decode() 119 | 120 | pk.Encode() 121 | 122 | conn.Client.WritePacket(pk.Buffer) 123 | } 124 | 125 | func (conn *Connection) HandleIncomingPackets() { 126 | for { 127 | buffer := make([]byte, 2048) 128 | _, addr, err := conn.Proxy.UDPConn.ReadFromUDP(buffer) 129 | 130 | if err != nil { 131 | Alert(err.Error()) 132 | continue 133 | } 134 | 135 | MessageId := buffer[0] 136 | 137 | if conn.Client.IsConnected() { 138 | if conn.IsServer(*addr) { 139 | conn.pkHandler.HandleIncomingPacket(buffer, conn.Client, *addr) 140 | } else { 141 | conn.pkHandler.HandleIncomingPacket(buffer, conn.Server, *addr) 142 | } 143 | continue 144 | } 145 | 146 | switch MessageId { 147 | case byte(IdUnconnectedPingOpenConnection): 148 | conn.handleUnconnectedPing(*addr, buffer) 149 | break 150 | case byte(IdUnconnectedPongOpenConnection): 151 | conn.handleUnconnectedPong(*addr, buffer) 152 | break 153 | case byte(IdOpenConnectionRequest1): 154 | conn.handleConnectionRequest1(*addr, buffer) 155 | break 156 | case byte(IdOpenConnectionReply1): 157 | conn.handleConnectionReply1(*addr, buffer) 158 | break 159 | case byte(IdOpenConnectionRequest2): 160 | conn.handleConnectionRequest2(*addr, buffer) 161 | break 162 | case byte(IdOpenConnectionReply2): 163 | conn.handleConnectionReply2(*addr, buffer) 164 | break 165 | } 166 | } 167 | } -------------------------------------------------------------------------------- /datagram_builder.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/Irmine/GoRakLib/protocol" 6 | ) 7 | 8 | // DatagramBuilds builds datagram 9 | // either from a packet or from raw bytes 10 | // datagrams are the communication method 11 | // for the RakNet protocol 12 | type DatagramBuilder struct { 13 | pkHandler *PacketHandler 14 | } 15 | 16 | func NewDatagramBuilder() DatagramBuilder { 17 | return DatagramBuilder{} 18 | } 19 | 20 | // this builds a datagram from packets 21 | // with the encode/decode function 22 | // and sets the order of the datagram 23 | // to the Proxy's own sequence number order 24 | func (db *DatagramBuilder) BuildFromPackets(packets []packets.IPacket) protocol.Datagram { 25 | db.pkHandler.orders.SequenceNumber++ 26 | datagram := db.BuildRawFromPackets(packets, Unreliable, db.pkHandler.orders.SequenceNumber, 0, 0) 27 | return datagram 28 | } 29 | 30 | // this builds a datagram from raw bytes 31 | // and sets the order of the datagram 32 | // to the Proxy's own sequence number order 33 | func (db *DatagramBuilder) BuildFromBuffer(packets []byte) protocol.Datagram { 34 | db.pkHandler.orders.SequenceNumber++ 35 | datagram := db.BuildRaw(append([][]byte{}, packets), Unreliable, db.pkHandler.orders.SequenceNumber, 0, 0) 36 | return datagram 37 | } 38 | 39 | // this builds a datagram from packets 40 | // with the encode/decode function 41 | // and sets the order of the datagram 42 | // to the latest sequence number received 43 | func (db *DatagramBuilder) BuildFromPacketsWithLatestSequence(packets []packets.IPacket) protocol.Datagram { 44 | db.pkHandler.lastSequenceNumber++ 45 | datagram := db.BuildRawFromPackets(packets, Unreliable, db.pkHandler.lastSequenceNumber, 0, 0) 46 | return datagram 47 | } 48 | 49 | // this builds a datagram from raw bytes 50 | // and sets the order of the datagram 51 | // to the latest sequence number received 52 | func (db *DatagramBuilder) BuildFromBufferWithLatestSequence(packets []byte) protocol.Datagram { 53 | db.pkHandler.lastSequenceNumber++ 54 | datagram := db.BuildRaw(append([][]byte{}, packets), Unreliable, db.pkHandler.lastSequenceNumber, 0, 0) 55 | return datagram 56 | } 57 | 58 | 59 | // this builds a datagram from a packet batch 60 | // and sets the reliability of the encapsulated 61 | // packet to a custom one and the order of the 62 | // datagram to a custom sequence number 63 | func (db *DatagramBuilder) BuildFromBatch(batch *MinecraftPacketBatch, reliability byte, sequenceNumber, orderIndex, messageIndex uint32) protocol.Datagram { 64 | encapsulated := protocol.NewEncapsulatedPacket() 65 | encapsulated.Reliability = reliability 66 | encapsulated.OrderIndex = orderIndex 67 | encapsulated.MessageIndex = messageIndex 68 | encapsulated.Buffer = batch.Buffer 69 | datagram := protocol.NewDatagram() 70 | datagram.SequenceNumber = sequenceNumber 71 | datagram.AddPacket(encapsulated) 72 | datagram.Encode() 73 | return *datagram 74 | } 75 | 76 | // this builds a datagram from a slice 77 | // of encapsulated packets and sets the 78 | // reliability of the encapsulated packet 79 | // to a custom one and the order of the 80 | // datagram to a custom sequence number 81 | func (db *DatagramBuilder) BuildFromEncapsulated(packets []*protocol.EncapsulatedPacket, sequenceNumber uint32) protocol.Datagram { 82 | datagram := protocol.NewDatagram() 83 | datagram.SequenceNumber = sequenceNumber 84 | for _, p := range packets { 85 | datagram.AddPacket(p) 86 | } 87 | datagram.Encode() 88 | return *datagram 89 | } 90 | 91 | // this builds a datagram from raw bytes 92 | // and sets the reliability of the 93 | // encapsulated packet to a custom one 94 | // and the order of the datagram 95 | // to a custom sequence number 96 | func (db *DatagramBuilder) BuildRaw(packets [][]byte, reliability byte, sequenceNumber, orderIndex, messageIndex uint32) protocol.Datagram { 97 | batch := NewMinecraftPacketBatch() 98 | batch.rawPackets = packets 99 | batch.Encode() 100 | encapsulated := protocol.NewEncapsulatedPacket() 101 | encapsulated.Reliability = reliability 102 | encapsulated.OrderIndex = orderIndex 103 | encapsulated.MessageIndex = messageIndex 104 | encapsulated.Buffer = batch.Buffer 105 | datagram := protocol.NewDatagram() 106 | datagram.SequenceNumber = sequenceNumber 107 | datagram.AddPacket(encapsulated) 108 | datagram.Encode() 109 | return *datagram 110 | } 111 | 112 | // this builds a datagram from packets 113 | // with the encode/decode function 114 | // and sets the reliability of the 115 | // encapsulated packet to a custom one 116 | // and the order of the datagram 117 | // to a custom sequence number 118 | func (db *DatagramBuilder) BuildRawFromPackets(packets []packets.IPacket, reliability byte, sequenceNumber, orderIndex, messageIndex uint32) protocol.Datagram { 119 | batch := NewMinecraftPacketBatch() 120 | for _, p := range packets { 121 | batch.AddPacket(p) 122 | } 123 | batch.Encode() 124 | encapsulated := protocol.NewEncapsulatedPacket() 125 | encapsulated.HasSplit = false 126 | encapsulated.Reliability = reliability 127 | encapsulated.OrderIndex = orderIndex 128 | encapsulated.MessageIndex = messageIndex 129 | encapsulated.Buffer = batch.Buffer 130 | datagram := protocol.NewDatagram() 131 | datagram.SequenceNumber = sequenceNumber 132 | datagram.AddPacket(encapsulated) 133 | datagram.Encode() 134 | return *datagram 135 | } -------------------------------------------------------------------------------- /default_handlers.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "github.com/infinitygamers/goproxy/info" 5 | "github.com/infinitygamers/goproxy/packets" 6 | ) 7 | 8 | func RegisterDefaultHandlers(pkHandler *PacketHandler) { 9 | pkHandler.RegisterHandler(info.MovePlayerPacket, func(bytes []byte, host Host, connection *Connection) bool { 10 | move := packets.NewMovePlayerPacket() 11 | move.Buffer = bytes 12 | move.DecodeHeader() 13 | move.Decode() 14 | 15 | if host.IsServer() { 16 | connection.Client.Position = move.Position 17 | } 18 | 19 | return false 20 | }) 21 | } -------------------------------------------------------------------------------- /host.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "net" 5 | "github.com/Irmine/GoMine/net/packets" 6 | ) 7 | 8 | type Host interface { 9 | WritePacket(buffer []byte) 10 | SendPacket(packets.IPacket) 11 | SendBatchPacket([]packets.IPacket) 12 | GetAddress() net.UDPAddr 13 | IsClient() bool 14 | IsServer() bool 15 | } -------------------------------------------------------------------------------- /info/info.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | 4 | const ( 5 | LoginPacket = 0x01 6 | PlayStatusPacket = 0x02 7 | ServerHandshakePacket = 0x03 8 | ClientHandshakePacket = 0x04 9 | DisconnectPacket = 0x05 10 | ResourcePackInfoPacket = 0x06 11 | ResourcePackStackPacket = 0x07 12 | ResourcePackClientResponsePacket= 0x08 13 | TextPacket = 0x09 14 | SetTimePacket = 0x0a 15 | StartGamePacket = 0x0b 16 | AddPlayerPacket = 0x0c 17 | AddEntityPacket = 0x0d 18 | RemoveEntityPacket = 0x0e 19 | AddItemEntityPacket = 0x0f 20 | AddHangingEntityPacket = 0x10 21 | TakeItemEntityPacket = 0x11 22 | MoveEntityPacket = 0x12 23 | MovePlayerPacket = 0x13 24 | RiderJumpPacket = 0x14 25 | UpdateBlockPacket = 0x15 26 | AddPaintingPacket = 0x16 27 | ExplodePacket = 0x17 28 | LevelSoundEventPacket = 0x18 29 | LevelEventPacket = 0x19 30 | BlockEventPacket = 0x1a 31 | EntityEventPacket = 0x1b 32 | MobEffectPacket = 0x1c 33 | UpdateAttributesPacket = 0x1d 34 | InventoryTransactionPacket = 0x1e 35 | MobEquipmentPacket = 0x1f 36 | MobArmorEquipmentPacket = 0x20 37 | InteractPacket = 0x21 38 | BlockPickRequestPacket = 0x22 39 | EntityPickRequestPacket = 0x23 40 | PlayerActionPacket = 0x24 41 | EntityFallPacket = 0x25 42 | HurtArmorPacket = 0x26 43 | SetEntityDataPacket = 0x27 44 | SetEntityMotionPacket = 0x28 45 | SetEntityLinkPacket = 0x29 46 | SetHealthPacket = 0x2a 47 | SetSpawnPositionPacket = 0x2b 48 | AnimatePacket = 0x2c 49 | RespawnPacket = 0x2d 50 | ContainerOpenPacket = 0x2e 51 | ContainerClosePacket = 0x2f 52 | PlayerHotbarPacket = 0x30 53 | InventoryContentPacket = 0x31 54 | InventorySlotPacket = 0x32 55 | ContainerSetDataPacket = 0x33 56 | CraftingDataPacket = 0x34 57 | CraftingEventPacket = 0x35 58 | GuiDataPickItemPacket = 0x36 59 | AdventureSettingsPacket = 0x37 60 | BlockEntityDataPacket = 0x38 61 | PlayerInputPacket = 0x39 62 | FullChunkDataPacket = 0x3a 63 | SetCommandsEnabledPacket = 0x3b 64 | SetDifficultyPacket = 0x3c 65 | ChangeDimensionPacket = 0x3d 66 | SetPlayerGameTypePacket = 0x3e 67 | PlayerListPacket = 0x3f 68 | SimpleEventPacket = 0x40 69 | EventPacket = 0x41 70 | SpawnExperienceOrbPacket = 0x42 71 | ClientboundMapItemDataPacket = 0x43 72 | MapInfoRequestPacket = 0x44 73 | RequestChunkRadiusPacket = 0x45 74 | ChunkRadiusUpdatedPacket = 0x46 75 | ItemFrameDropItemPacket = 0x47 76 | GameRulesChangedPacket = 0x48 77 | CameraPacket = 0x49 78 | BossEventPacket = 0x4a 79 | ShowCreditsPacket = 0x4b 80 | AvailableCommandsPacket = 0x4c 81 | CommandRequestPacket = 0x4d 82 | CommandBlockUpdatePacket = 0x4e 83 | CommandOutputPacket = 0x4f 84 | UpdateTradePacket = 0x50 85 | UpdateEquipPacket = 0x51 86 | ResourcePackDataInfoPacket = 0x52 87 | ResourcePackChunkDataPacket = 0x53 88 | ResourcePackChunkRequestPacket = 0x54 89 | TransferPacket = 0x55 90 | PlaySoundPacket = 0x56 91 | StopSoundPacket = 0x57 92 | SetTitlePacket = 0x58 93 | AddBehaviorTreePacket = 0x59 94 | StructureBlockUpdatePacket = 0x5a 95 | ShowStoreOfferPacket = 0x5b 96 | PurchaseReceiptPacket = 0x5c 97 | PlayerSkinPacket = 0x5d 98 | SubClientLoginPacket = 0x5e 99 | WSConnectPacket = 0x5f 100 | SetLastHurtByPacket = 0x60 101 | BookEditPacket = 0x61 102 | NpcRequestPacket = 0x62 103 | PhotoTransferPacket = 0x63 104 | ModalFormRequestPacket = 0x64 105 | ModalFormResponsePacket = 0x65 106 | ServerSettingsRequestPacket = 0x66 107 | ServerSettingsResponsePacket = 0x67 108 | ShowProfilePacket = 0x68 109 | SetDefaultGameTypePacket = 0x69 110 | ) -------------------------------------------------------------------------------- /logger.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "time" 5 | "fmt" 6 | ) 7 | 8 | const ( 9 | AnsiPre = "\u001b[" 10 | AnsiReset = AnsiPre + "0m" 11 | 12 | AnsiBold = AnsiPre + "1m" 13 | AnsiItalic = AnsiPre + "3m" 14 | AnsiUnderlined = AnsiPre + "4m" 15 | 16 | AnsiBlack = AnsiPre + "30m" 17 | AnsiRed = AnsiPre + "31m" 18 | AnsiGreen = AnsiPre + "32m" 19 | AnsiYellow = AnsiPre + "33m" 20 | AnsiBlue = AnsiPre + "34m" 21 | AnsiMagenta = AnsiPre + "35m" 22 | AnsiCyan = AnsiPre + "36m" 23 | AnsiWhite = AnsiPre + "37m" 24 | AnsiGray = AnsiPre + "30;1m" 25 | 26 | AnsiBrightRed = AnsiPre + "31;1m" 27 | AnsiBrightGreen = AnsiPre + "32;1m" 28 | AnsiBrightYellow = AnsiPre + "33;1m" 29 | AnsiBrightBlue = AnsiPre + "34;1m" 30 | AnsiBrightMagenta = AnsiPre + "35;1m" 31 | AnsiBrightCyan = AnsiPre + "36;1m" 32 | AnsiBrightWhite = AnsiPre + "37;1m" 33 | ) 34 | 35 | const ( 36 | Pre = "§" 37 | 38 | Black = Pre + "0" 39 | Blue = Pre + "1" 40 | Green = Pre + "2" 41 | Cyan = Pre + "3" 42 | Red = Pre + "4" 43 | Magenta = Pre + "5" 44 | Orange = Pre + "6" 45 | BrightGray = Pre + "7" 46 | Gray = Pre + "8" 47 | BrightBlue = Pre + "9" 48 | 49 | BrightGreen = Pre + "a" 50 | BrightCyan = Pre + "b" 51 | BrightRed = Pre + "c" 52 | BrightMagenta = Pre + "d" 53 | Yellow = Pre + "e" 54 | White = Pre + "f" 55 | 56 | Obfuscated = Pre + "k" 57 | Bold = Pre + "l" 58 | StrikeThrough = Pre + "m" 59 | Underlined = Pre + "n" 60 | Italic = Pre + "o" 61 | 62 | Reset = Pre + "r" 63 | ) 64 | 65 | const ( 66 | InfoPrefix = "INFO" 67 | AlertPrefix = "ALERT" 68 | NoticePrefix = "NOTICE" 69 | DebugPrefix = "DEBUG" 70 | PanicPrefix = "PANIC" 71 | ) 72 | 73 | // returns a log prefix with custom prefix 74 | func LogFormat(prefix string) string { 75 | now := time.Now() 76 | return "[" + now.Format("2006-01-02 15:04:05") + "][Log/" + prefix + "]: " 77 | } 78 | 79 | func Info(log ...interface{}) { 80 | fmt.Print(AnsiYellow, LogFormat(InfoPrefix), AnsiWhite) 81 | fmt.Println(log...) 82 | } 83 | 84 | func Alert(log ...interface{}) { 85 | fmt.Print(AnsiRed, LogFormat(AlertPrefix), AnsiYellow) 86 | fmt.Println(log...) 87 | } 88 | 89 | func Notice(log ...interface{}) { 90 | fmt.Print(AnsiCyan, LogFormat(NoticePrefix), AnsiWhite) 91 | fmt.Println(log...) 92 | } 93 | 94 | func Debug(log ...interface{}) { 95 | fmt.Print(AnsiWhite, LogFormat(DebugPrefix), AnsiWhite) 96 | fmt.Println(log...) 97 | } 98 | 99 | func Panic(log ...interface{}) { 100 | fmt.Print(AnsiBold, AnsiRed, LogFormat(PanicPrefix)) 101 | fmt.Println(log...) 102 | } -------------------------------------------------------------------------------- /minecraft_batch_packet.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "github.com/irmine/binutils" 5 | "github.com/Irmine/GoMine/net/packets" 6 | "bytes" 7 | "compress/zlib" 8 | "io/ioutil" 9 | ) 10 | 11 | const ( 12 | BatchId = 0xFE 13 | ) 14 | 15 | type MinecraftPacketBatch struct { 16 | *binutils.Stream 17 | rawPackets [][]byte 18 | } 19 | 20 | func NewMinecraftPacketBatch() *MinecraftPacketBatch { 21 | var batch = &MinecraftPacketBatch{} 22 | batch.Stream = binutils.NewStream() 23 | return batch 24 | } 25 | 26 | func (batch *MinecraftPacketBatch) AddPacket(packet packets.IPacket) { 27 | packet.EncodeHeader() 28 | packet.Encode() 29 | batch.AddRawPacket(packet.GetBuffer()) 30 | } 31 | 32 | func (batch *MinecraftPacketBatch) AddRawPacket(packet []byte) { 33 | batch.rawPackets = append(batch.rawPackets, packet) 34 | } 35 | 36 | func (batch *MinecraftPacketBatch) GetRawPackets() [][]byte { 37 | return batch.rawPackets 38 | } 39 | 40 | func (batch *MinecraftPacketBatch) Encode() { 41 | batch.ResetStream() 42 | batch.PutByte(BatchId) 43 | 44 | stream := binutils.NewStream() 45 | for _, p := range batch.rawPackets { 46 | stream.PutLengthPrefixedBytes(p) 47 | } 48 | 49 | // zlib compression 50 | buffer := bytes.Buffer{} 51 | writer := zlib.NewWriter(&buffer) 52 | writer.Write(stream.Buffer) 53 | writer.Close() 54 | 55 | batch.PutBytes(buffer.Bytes()) 56 | } 57 | 58 | func (batch *MinecraftPacketBatch) Decode() { 59 | defer func() { 60 | if err := recover(); err != nil { 61 | Alert(err) 62 | } 63 | }() 64 | 65 | batchId := batch.GetByte() 66 | 67 | if batchId != BatchId { 68 | Notice("Packet received is not batch:", batchId) 69 | return 70 | } 71 | 72 | data := batch.Buffer[batch.Offset:] 73 | 74 | reader := bytes.NewReader(data) 75 | zlibReader, err := zlib.NewReader(reader) 76 | 77 | if err != nil { 78 | Alert("Zlib Reader Error:", err) 79 | return 80 | } 81 | 82 | if zlibReader == nil { 83 | Alert("Error while reading from zlib") 84 | return 85 | } 86 | 87 | zlibReader.Close() 88 | 89 | data, err = ioutil.ReadAll(zlibReader) 90 | 91 | if err != nil { 92 | Alert("ioutil Error:", err) 93 | return 94 | } 95 | 96 | batch.ResetStream() 97 | batch.SetBuffer(data) 98 | 99 | for !batch.Feof() { 100 | batch.rawPackets = append(batch.rawPackets, batch.GetLengthPrefixedBytes()) 101 | } 102 | } -------------------------------------------------------------------------------- /packet_handler.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "net" 5 | "github.com/Irmine/GoRakLib/protocol" 6 | "github.com/Irmine/GoMine/net/packets" 7 | ) 8 | 9 | const ( 10 | ClientHandshakeId = 0x13 11 | ClientCancelConnectId = 0x15 12 | ) 13 | 14 | // Indexes is used for the collection of indexes related to datagrams and encapsulated packets. 15 | // It uses several maps and is therefore protected by a mutex. 16 | type Indexes struct { 17 | splits map[int16][]*protocol.EncapsulatedPacket 18 | splitCounts map[int16]uint 19 | splitId int16 20 | } 21 | 22 | // Orders is used to re-order the indexes of encapsulated packets 23 | // this is to avoid message order conflicts with the Client and Server 24 | type Orders struct { 25 | //SplitIndex uint 26 | 27 | // the last encapsulated order 28 | // index number from both hosts 29 | ///OrderIndex uint32 30 | 31 | // the last encapsulated 32 | // message index number from both hosts 33 | //MessageIndex uint32 34 | 35 | // the last datagram sequence 36 | // number from both hosts 37 | SequenceNumber uint32 38 | } 39 | 40 | // PacketHandler handles each datagram and 41 | // calls all registered packet handlers to handle the packet, 42 | // once ready, sends it to the right host 43 | type PacketHandler struct { 44 | // Connection is the Connection between the 45 | // Server and the Client 46 | Conn *Connection 47 | // a map where handler functions are stored 48 | // parameters: 49 | // 1. the bytes received from the packet 50 | // 2. the host to where the packet is headed 51 | // 3. the Connection between the Server and Client 52 | // return true if the packet should be cancelled 53 | handlers map[byte][]func([]byte, Host, *Connection) bool 54 | // used for the collection of indexes 55 | // related to datagrams and encapsulated packets. 56 | splits Indexes 57 | // Orders is used to re-order 58 | // the indexes of encapsulated packets 59 | // this is to avoid message order 60 | // conflicts with the Client and Server 61 | orders Orders 62 | // DatagramBuilds builds datagram 63 | // either from a packet or from raw bytes 64 | // datagrams are the communication method 65 | // for the RakNet protocol 66 | DatagramBuilder DatagramBuilder 67 | // the number of the last datagram 68 | // sent by both hosts 69 | lastSequenceNumber uint32 70 | // the last datagram received from both hosts 71 | datagram *protocol.Datagram 72 | // a slice of raw packets that will be 73 | // sent out to the client next tick, packets are sent 74 | // every tick via the packet handler, 75 | // 20 ticks = 1 second, 1 tick ~ 0.05 seconds 76 | OutBoundPacketsClient [][]byte 77 | // a slice of raw packets that will be 78 | // sent out to the server next tick, packets are sent 79 | // every tick via the packet handler, 80 | // 20 ticks = 1 second, 1 tick ~ 0.05 seconds 81 | OutBoundPacketsServer [][]byte 82 | // a bool that returns true if the 83 | // Client is ready for packets 84 | Ready bool 85 | } 86 | 87 | // returns a new packet handler 88 | // PacketHandler handles each datagram and 89 | // calls all registered packet handlers to handle the packet, 90 | // once ready, sends it to the right host 91 | func NewPacketHandler() *PacketHandler { 92 | h := PacketHandler{} 93 | h.handlers = make(map[byte][]func([]byte, Host, *Connection) bool) 94 | h.splits = Indexes{splits: make(map[int16][]*protocol.EncapsulatedPacket), splitCounts: make(map[int16]uint)} 95 | h.DatagramBuilder = NewDatagramBuilder() 96 | h.DatagramBuilder.pkHandler = &h 97 | h.OutBoundPacketsClient = [][]byte{} 98 | h.OutBoundPacketsServer = [][]byte{} 99 | h.orders = Orders{} 100 | return &h 101 | } 102 | 103 | // registers a packet handler with a certain packet id 104 | // every function should have these parameters: 105 | // 1. the bytes received from the packet 106 | // 2. the host to where the packet is headed 107 | // 3. the Connection between the Server and Client 108 | // return true if the packet should be cancelled 109 | func (pkHandler *PacketHandler) RegisterHandler(pkId byte, f func([]byte, Host, *Connection) bool) { 110 | if _, ok := pkHandler.handlers[pkId]; !ok { 111 | pkHandler.handlers[pkId] = []func([]byte, Host, *Connection) bool {} 112 | } 113 | pkHandler.handlers[pkId] = append(pkHandler.handlers[pkId], f) 114 | } 115 | 116 | // calls packet handlers for a certain packet id 117 | // returns true if some handler cancelled the packet 118 | func (pkHandler *PacketHandler) CallPacketHandlers(pkId byte, host Host, packet []byte) bool { 119 | cancelled := false 120 | if _, ok := pkHandler.handlers[pkId]; ok { 121 | for _, v := range pkHandler.handlers[pkId] { 122 | if v(packet, host, pkHandler.Conn) { 123 | cancelled = true 124 | } 125 | } 126 | } 127 | return cancelled //return true if packet is cancelled 128 | } 129 | 130 | // Sends the last datagram received from one host 131 | // to the other host 132 | func (pkHandler *PacketHandler) FlowDatagram(host Host) { 133 | datagram := pkHandler.datagram 134 | datagram.Encode() 135 | host.WritePacket(datagram.Buffer) 136 | } 137 | 138 | // adds a packet to the slice of 139 | // packets that will be sent out to the client next tick, 140 | // packets are sent every tick via the packet handler, 141 | // 20 ticks = 1 second, 1 tick ~ 0.05 seconds 142 | func (pkHandler *PacketHandler) AddOutboundPacketClient(packet packets.IPacket) { 143 | packet.EncodeHeader() 144 | packet.Encode() 145 | pkHandler.OutBoundPacketsClient = append(pkHandler.OutBoundPacketsClient, packet.GetBuffer()) 146 | } 147 | 148 | // adds a raw packet to the slice of 149 | // packets that will be sent out to the client next tick, 150 | // packets are sent every tick via the packet handler, 151 | // 20 ticks = 1 second, 1 tick ~ 0.05 seconds 152 | func (pkHandler *PacketHandler) AddOutboundRawPacketClient(packet []byte) { 153 | pkHandler.OutBoundPacketsClient = append(pkHandler.OutBoundPacketsClient, packet) 154 | } 155 | 156 | // adds a packet to the slice of 157 | // packets that will be sent out to the server next tick, 158 | // packets are sent every tick via the packet handler, 159 | // 20 ticks = 1 second, 1 tick ~ 0.05 seconds 160 | func (pkHandler *PacketHandler) AddOutboundPacketServer(packet packets.IPacket) { 161 | packet.EncodeHeader() 162 | packet.Encode() 163 | pkHandler.OutBoundPacketsServer = append(pkHandler.OutBoundPacketsServer, packet.GetBuffer()) 164 | } 165 | 166 | // adds a raw packet to the slice of 167 | // packets that will be sent out to the server next tick, 168 | // packets are sent every tick via the packet handler, 169 | // 20 ticks = 1 second, 1 tick ~ 0.05 seconds 170 | func (pkHandler *PacketHandler) AddOutboundRawPacketServer(packet []byte) { 171 | pkHandler.OutBoundPacketsServer = append(pkHandler.OutBoundPacketsServer, packet) 172 | } 173 | 174 | // handles encapsulated packet 175 | // if the packet is batch it will call the packet handlers 176 | // if not it will just continue on sending the datagram 177 | func (pkHandler *PacketHandler) HandleEncapsulated(packet *protocol.EncapsulatedPacket, host Host, addr net.UDPAddr) bool { 178 | handled := false 179 | PkId := packet.Buffer[0] 180 | if PkId == BatchId { 181 | if pkHandler.Ready { 182 | batch := NewMinecraftPacketBatch() 183 | batch.SetBuffer(packet.Buffer) 184 | batch.Decode() 185 | batch2 := NewMinecraftPacketBatch() 186 | 187 | for _, pk := range batch.GetRawPackets() { 188 | pkId := pk[0] 189 | if !pkHandler.CallPacketHandlers(pkId, host, pk) { 190 | batch2.AddRawPacket(pk) 191 | } 192 | } 193 | 194 | if host.IsServer() { 195 | if toServer := pkHandler.OutBoundPacketsServer; len(toServer) > 0 { 196 | for _, pk := range toServer { 197 | batch2.AddRawPacket(pk) 198 | } 199 | pkHandler.OutBoundPacketsServer = nil 200 | } 201 | }else{ 202 | if toClient := pkHandler.OutBoundPacketsClient; len(toClient) > 0 { 203 | for _, pk := range toClient { 204 | batch2.AddRawPacket(pk) 205 | } 206 | pkHandler.OutBoundPacketsClient = nil 207 | } 208 | } 209 | 210 | batch2.Encode() 211 | encap := protocol.NewEncapsulatedPacket() 212 | encap.Buffer = batch2.Buffer 213 | encap.Reliability = packet.Reliability 214 | encap.HasSplit = false 215 | encap.Length = packet.Length 216 | encap.MessageIndex = packet.MessageIndex 217 | encap.OrderIndex = packet.OrderIndex 218 | dgram := protocol.NewDatagram() 219 | dgram.AddPacket(encap) 220 | dgram.SequenceNumber = pkHandler.lastSequenceNumber 221 | dgram.Encode() 222 | 223 | host.WritePacket(dgram.Buffer) 224 | 225 | handled = true 226 | } 227 | 228 | }else if PkId == ClientHandshakeId { 229 | Info(AnsiGreen + "Client has connected to the Server.") 230 | pkHandler.FlowDatagram(host) 231 | pkHandler.Conn.Client.SendJoinMessage() 232 | pkHandler.Ready = true 233 | handled = true 234 | } else if PkId == ClientCancelConnectId { 235 | Info(AnsiBrightRed + "Client has disconnected from the Server.") 236 | pkHandler.Conn.Client.SetConnected(false) 237 | pkHandler.FlowDatagram(host) 238 | pkHandler.Ready = false 239 | handled = true 240 | } else { 241 | 242 | switch PkId { 243 | case protocol.IdConnectionRequest: 244 | Info(AnsiBrightCyan + "Connection request from client") 245 | case protocol.IdConnectionAccept: 246 | Info(AnsiBrightCyan + "Connection request accepted from server") 247 | } 248 | 249 | pkHandler.FlowDatagram(host) 250 | handled = true 251 | } 252 | return handled 253 | } 254 | 255 | // Decodes a split encapsulated packet 256 | // and turns it into one 257 | func (pkHandler *PacketHandler) DecodeSplit(packet *protocol.EncapsulatedPacket) *protocol.EncapsulatedPacket { 258 | id := packet.SplitId 259 | 260 | if pkHandler.splits.splits[id] == nil { 261 | pkHandler.splits.splits[id] = make([]*protocol.EncapsulatedPacket, packet.SplitCount) 262 | pkHandler.splits.splitCounts[id] = 0 263 | } 264 | 265 | if pk := pkHandler.splits.splits[id][packet.SplitIndex]; pk == nil { 266 | pkHandler.splits.splitCounts[id]++ 267 | } 268 | 269 | pkHandler.splits.splits[id][packet.SplitIndex] = packet 270 | 271 | if pkHandler.splits.splitCounts[id] == packet.SplitCount { 272 | newPacket := protocol.NewEncapsulatedPacket() 273 | for _, pk := range pkHandler.splits.splits[id] { 274 | newPacket.PutBytes(pk.Buffer) 275 | } 276 | 277 | delete(pkHandler.splits.splits, id) 278 | return newPacket 279 | } 280 | 281 | return nil 282 | } 283 | 284 | // this handles encapsulated packets that 285 | // come in more than one part, construct a single one 286 | // and calls the HandleEncapsulated function 287 | func (pkHandler *PacketHandler) HandleSplitEncapsulated(packet *protocol.EncapsulatedPacket, host Host, addr net.UDPAddr) bool { 288 | d := pkHandler.DecodeSplit(packet) 289 | 290 | if d != nil { 291 | return pkHandler.HandleEncapsulated(d, host, addr) 292 | } 293 | 294 | return false 295 | } 296 | 297 | // this handles all the incoming packets 298 | // after the Client has clicked the Server 299 | // of the Proxy 300 | func (pkHandler *PacketHandler) HandleIncomingPacket(buffer []byte, host Host, addr net.UDPAddr) { 301 | MessageId := buffer[0] 302 | if (MessageId & protocol.BitFlagValid) != 0 { 303 | if (MessageId & protocol.BitFlagIsNak) != 0 { 304 | nak := protocol.NewNAK() 305 | nak.SetBuffer(buffer) 306 | nak.Decode() 307 | nak.Encode() 308 | host.WritePacket(nak.Buffer) 309 | } else if (MessageId & protocol.BitFlagIsAck) != 0 { 310 | ack := protocol.NewACK() 311 | ack.SetBuffer(buffer) 312 | ack.Decode() 313 | ack.Encode() 314 | host.WritePacket(ack.Buffer) 315 | } else { 316 | datagram := protocol.NewDatagram() 317 | datagram.SetBuffer(buffer) 318 | datagram.Decode() 319 | 320 | pkHandler.datagram = datagram 321 | pkHandler.lastSequenceNumber = datagram.SequenceNumber 322 | packets2 := datagram.GetPackets() 323 | 324 | if len(*packets2) != 0 { 325 | for _, pk := range *packets2 { 326 | if pk.HasSplit { 327 | if !pkHandler.HandleSplitEncapsulated(pk, host, addr) { 328 | pkHandler.FlowDatagram(host) 329 | } 330 | } else { 331 | if !pkHandler.HandleEncapsulated(pk, host, addr) { 332 | pkHandler.FlowDatagram(host) 333 | } 334 | } 335 | } 336 | }else{ 337 | pkHandler.FlowDatagram(host) 338 | } 339 | } 340 | } else { 341 | host.WritePacket(buffer) 342 | } 343 | } -------------------------------------------------------------------------------- /packets/add_entity_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/golang/geo/r3" 5 | "github.com/Irmine/GoMine/net/packets" 6 | "github.com/irmine/worlds/entities/data" 7 | "github.com/infinitygamers/goproxy/info" 8 | ) 9 | 10 | type AddEntityPacket struct { 11 | *packets.Packet 12 | UniqueId int64 13 | RuntimeId uint64 14 | EntityType uint32 15 | Position r3.Vector 16 | Motion r3.Vector 17 | Rotation data.Rotation 18 | 19 | Attributes data.AttributeMap 20 | EntityData map[uint32][]interface{} 21 | } 22 | 23 | func NewAddEntityPacket() *AddEntityPacket { 24 | return &AddEntityPacket{packets.NewPacket(info.AddEntityPacket), 0, 0, 0, r3.Vector{}, r3.Vector{}, data.Rotation{}, data.NewAttributeMap(), nil} 25 | } 26 | 27 | func (pk *AddEntityPacket) Encode() { 28 | pk.PutEntityUniqueId(pk.UniqueId) 29 | pk.PutEntityRuntimeId(pk.RuntimeId) 30 | pk.PutUnsignedVarInt(pk.EntityType) 31 | pk.PutVector(pk.Position) 32 | pk.PutVector(pk.Motion) 33 | pk.PutEntityRotation(pk.Rotation) 34 | pk.PutAttributeMap(pk.Attributes) 35 | pk.PutEntityData(pk.EntityData) 36 | pk.PutUnsignedVarInt(0) 37 | } 38 | 39 | func (pk *AddEntityPacket) Decode() { 40 | pk.UniqueId = pk.GetEntityUniqueId() 41 | pk.RuntimeId = pk.GetEntityRuntimeId() 42 | pk.EntityType = pk.GetUnsignedVarInt() 43 | pk.Position = pk.GetVector() 44 | pk.Motion = pk.GetVector() 45 | pk.Rotation = pk.GetEntityRotation() 46 | pk.Attributes = pk.GetAttributeMap() 47 | pk.EntityData = pk.GetEntityData() 48 | } 49 | -------------------------------------------------------------------------------- /packets/add_player_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/google/uuid" 5 | "github.com/golang/geo/r3" 6 | "github.com/irmine/worlds/entities/data" 7 | "github.com/Irmine/GoMine/net/packets" 8 | "github.com/infinitygamers/goproxy/info" 9 | ) 10 | 11 | type AddPlayerPacket struct { 12 | *packets.Packet 13 | UUID uuid.UUID 14 | Username string 15 | DisplayName string 16 | Platform int32 17 | UnknownString string 18 | EntityUniqueId int64 19 | EntityRuntimeId uint64 20 | Position r3.Vector 21 | Motion r3.Vector 22 | Rotation data.Rotation 23 | // HandItem TODO: Items. 24 | Metadata map[uint32][]interface{} 25 | Flags uint32 26 | CommandPermission uint32 27 | Flags2 uint32 28 | PlayerPermission uint32 29 | CustomFlags uint32 30 | Long1 int64 31 | } 32 | 33 | func NewAddPlayerPacket() *AddPlayerPacket { 34 | return &AddPlayerPacket{Packet: packets.NewPacket(info.AddPlayerPacket), Metadata: make(map[uint32][]interface{}), Motion: r3.Vector{}} 35 | } 36 | 37 | func (pk *AddPlayerPacket) Encode() { 38 | pk.PutUUID(pk.UUID) 39 | pk.PutString(pk.Username) 40 | pk.PutString(pk.DisplayName) 41 | pk.PutVarInt(pk.Platform) 42 | 43 | pk.PutEntityUniqueId(pk.EntityUniqueId) 44 | pk.PutEntityRuntimeId(pk.EntityRuntimeId) 45 | pk.PutString(pk.UnknownString) 46 | 47 | pk.PutVector(pk.Position) 48 | pk.PutVector(pk.Motion) 49 | pk.PutPlayerRotation(pk.Rotation) 50 | 51 | pk.PutVarInt(0) // TODO 52 | pk.PutEntityData(pk.Metadata) 53 | 54 | pk.PutUnsignedVarInt(pk.Flags) 55 | pk.PutUnsignedVarInt(pk.CommandPermission) 56 | pk.PutUnsignedVarInt(pk.Flags2) 57 | pk.PutUnsignedVarInt(pk.PlayerPermission) 58 | pk.PutUnsignedVarInt(pk.CustomFlags) 59 | 60 | pk.PutVarLong(pk.Long1) 61 | 62 | pk.PutUnsignedVarInt(0) // TODO 63 | } 64 | 65 | func (pk *AddPlayerPacket) Decode() { 66 | pk.UUID = pk.GetUUID() 67 | pk.Username = pk.GetString() 68 | pk.DisplayName = pk.GetString() 69 | pk.Platform = pk.GetVarInt() 70 | 71 | pk.EntityUniqueId = pk.GetEntityUniqueId() 72 | pk.EntityRuntimeId = pk.GetEntityRuntimeId() 73 | pk.UnknownString = pk.GetString() 74 | 75 | pk.Position = pk.GetVector() 76 | pk.Motion = pk.GetVector() 77 | pk.Rotation = pk.GetPlayerRotation() 78 | 79 | pk.GetVarInt() 80 | pk.Metadata = pk.GetEntityData() 81 | 82 | pk.Flags = pk.GetUnsignedVarInt() 83 | pk.CommandPermission = pk.GetUnsignedVarInt() 84 | pk.Flags2 = pk.GetUnsignedVarInt() 85 | pk.PlayerPermission = pk.GetUnsignedVarInt() 86 | pk.CustomFlags = pk.GetUnsignedVarInt() 87 | 88 | pk.Long1 = pk.GetVarLong() 89 | 90 | pk.GetUnsignedVarInt() 91 | } 92 | -------------------------------------------------------------------------------- /packets/interact_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | const ( 9 | RightClick = 1 10 | LeftClick = 2 11 | LeaveCehicle = 3 12 | MouseOver = 4 13 | ) 14 | 15 | type InteractPacket struct { 16 | *packets.Packet 17 | Action byte 18 | RuntimeId uint64 19 | } 20 | 21 | func NewInteractPacket() *InteractPacket { 22 | return &InteractPacket{ packets.NewPacket(info.SetPlayerGameTypePacket), 0, 0} 23 | } 24 | 25 | func (pk *InteractPacket) Encode() { 26 | pk.PutByte(pk.Action) 27 | pk.PutUnsignedVarLong(pk.RuntimeId) 28 | } 29 | 30 | func (pk *InteractPacket) Decode() { 31 | pk.Action = pk.GetByte() 32 | pk.RuntimeId = pk.GetUnsignedVarLong() 33 | } -------------------------------------------------------------------------------- /packets/inventory_transaction_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/golang/geo/r3" 5 | "github.com/irmine/gomine/net/info" 6 | "github.com/Irmine/GoMine/net/packets" 7 | "github.com/infinitygamers/goproxy/packets/inventoryio" 8 | "github.com/infinitygamers/goproxy/packets/inventoryio/stream" 9 | ) 10 | 11 | /** 12 | * Transaction Types 13 | */ 14 | const ( 15 | Normal = iota + 0 16 | Mismatch 17 | UseItem 18 | UseItemOnEntity 19 | ReleaseItem 20 | ) 21 | 22 | // Action Types 23 | const ( 24 | ItemClickBlock = iota + 0 25 | ItemClickAir 26 | ItemBreakBlock 27 | 28 | //CONSUMABLE ITEMS 29 | ItemRelease = iota + 0 30 | ItemConsume 31 | ) 32 | 33 | // Entity Action ztypes 34 | const ( 35 | ItemOnEntityInteract = iota + 0 36 | ItemOnEntityAttack 37 | ) 38 | 39 | type InventoryTransactionPacket struct { 40 | *packets.Packet 41 | InvStream *stream.InventoryActionStream 42 | ActionList *inventoryio.InventoryActionIOList 43 | TransactionType, ActionType uint32 44 | Face, HotbarSlot int32 45 | ItemSlot *stream.VirtualItem 46 | BlockX int32 47 | BlockY uint32 48 | BlockZ int32 49 | PlayerPosition, ClickPosition, HeadPosition r3.Vector 50 | RuntimeId uint64 51 | } 52 | 53 | func NewInventoryTransactionPacket() *InventoryTransactionPacket { 54 | pk := &InventoryTransactionPacket{Packet: packets.NewPacket(info.PacketIds200[info.InventoryTransactionPacket]), 55 | ActionList: inventoryio.NewInventoryActionIOList(), 56 | TransactionType: 0, 57 | ActionType: 0, 58 | Face: 0, 59 | HotbarSlot: 0, 60 | ItemSlot: &stream.VirtualItem{}, 61 | PlayerPosition: r3.Vector{}, 62 | ClickPosition: r3.Vector{}, 63 | HeadPosition: r3.Vector{}, 64 | RuntimeId: 0, 65 | } 66 | pk.InvStream = stream.NewInventoryActionStream(pk.Stream) 67 | return pk 68 | } 69 | 70 | 71 | func (pk *InventoryTransactionPacket) GetBlockPos() { 72 | pk.BlockX = pk.GetVarInt() 73 | pk.BlockY = pk.GetUnsignedVarInt() 74 | pk.BlockZ = pk.GetVarInt() 75 | } 76 | 77 | func (pk *InventoryTransactionPacket) PutBlockPos() { 78 | pk.PutVarInt(pk.BlockX) 79 | pk.PutUnsignedVarInt(pk.BlockY) 80 | pk.PutVarInt(pk.BlockZ) 81 | } 82 | 83 | func (pk *InventoryTransactionPacket) Encode() { 84 | pk.PutUnsignedVarInt(pk.TransactionType) 85 | pk.ActionList.WriteToBuffer(pk.InvStream) 86 | 87 | switch pk.TransactionType { 88 | case Normal, Mismatch: 89 | break 90 | case UseItem: 91 | pk.PutUnsignedVarInt(pk.ActionType) 92 | pk.PutBlockPos() 93 | pk.PutVarInt(pk.Face) 94 | pk.PutVarInt(pk.HotbarSlot) 95 | pk.InvStream.PutVirtualItem(pk.ItemSlot) 96 | pk.PutVector(pk.PlayerPosition) 97 | pk.PutVector(pk.ClickPosition) 98 | break 99 | case UseItemOnEntity: 100 | pk.PutUnsignedVarLong(pk.RuntimeId) 101 | pk.PutUnsignedVarInt(pk.ActionType) 102 | pk.PutVarInt(pk.HotbarSlot) 103 | pk.InvStream.PutVirtualItem(pk.ItemSlot) 104 | pk.PutVector(pk.PlayerPosition) 105 | pk.PutVector(pk.ClickPosition) 106 | break 107 | case ReleaseItem: 108 | pk.PutUnsignedVarInt(pk.ActionType) 109 | pk.PutVarInt(pk.HotbarSlot) 110 | pk.InvStream.PutVirtualItem(pk.ItemSlot) 111 | pk.PutVector(pk.HeadPosition) 112 | break 113 | default: 114 | panic("Unknown transaction type passed: " + string(pk.TransactionType)) 115 | } 116 | } 117 | 118 | func (pk *InventoryTransactionPacket) Decode() { 119 | pk.TransactionType = pk.GetUnsignedVarInt() 120 | 121 | pk.ActionList.ReadFromBuffer(pk.InvStream) 122 | 123 | switch pk.TransactionType{ 124 | case Normal, Mismatch: 125 | break 126 | case UseItem: 127 | pk.ActionType = pk.GetUnsignedVarInt() 128 | pk.GetBlockPos() 129 | pk.Face = pk.GetVarInt() 130 | pk.HotbarSlot = pk.GetVarInt() 131 | pk.ItemSlot = pk.InvStream.GetVirtualItem() 132 | pk.PlayerPosition = pk.GetVector() 133 | pk.ClickPosition = pk.GetVector() 134 | case UseItemOnEntity: 135 | pk.RuntimeId = pk.GetUnsignedVarLong() 136 | pk.ActionType = pk.GetUnsignedVarInt() 137 | pk.HotbarSlot = pk.GetVarInt() 138 | pk.ItemSlot = pk.InvStream.GetVirtualItem() 139 | pk.PlayerPosition = pk.GetVector() 140 | pk.ClickPosition = pk.GetVector() 141 | case ReleaseItem: 142 | pk.ActionType = pk.GetUnsignedVarInt() 143 | pk.HotbarSlot = pk.GetVarInt() 144 | pk.ItemSlot = pk.InvStream.GetVirtualItem() 145 | pk.HeadPosition = pk.GetVector() 146 | default: 147 | panic("Error: Unknown transaction type received: " + string(pk.TransactionType)) 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /packets/inventoryio/inventory_action_io.go: -------------------------------------------------------------------------------- 1 | package inventoryio 2 | 3 | import ( 4 | "github.com/infinitygamers/goproxy/packets/inventoryio/stream" 5 | ) 6 | 7 | const ( 8 | ContainerSource = iota + 0 9 | WorldSource = 2 10 | //CreativeSource = 3 11 | ) 12 | 13 | type InventoryActionIO struct { 14 | Source uint32 15 | WindowId int32 16 | SourceFlags uint32 17 | InventorySlot uint32 18 | OldItem *stream.VirtualItem 19 | NewItem *stream.VirtualItem 20 | } 21 | 22 | func NewInventoryActionIO() InventoryActionIO{ 23 | return InventoryActionIO{} 24 | } 25 | 26 | func (IO *InventoryActionIO) WriteToBuffer(bs *stream.InventoryActionStream) { 27 | bs.PutUnsignedVarInt(IO.Source) 28 | 29 | switch IO.Source { 30 | case ContainerSource: 31 | bs.PutVarInt(IO.WindowId) 32 | break 33 | case WorldSource: 34 | bs.PutUnsignedVarInt(IO.SourceFlags) 35 | break 36 | } 37 | 38 | bs.PutUnsignedVarInt(IO.InventorySlot) 39 | bs.PutVirtualItem(IO.OldItem) 40 | bs.PutVirtualItem(IO.NewItem) 41 | } 42 | 43 | func (IO *InventoryActionIO) ReadFromBuffer(bs *stream.InventoryActionStream) InventoryActionIO { 44 | v := NewInventoryActionIO() 45 | v.Source = bs.GetUnsignedVarInt() 46 | switch v.Source { 47 | case ContainerSource: 48 | v.WindowId = bs.GetVarInt() 49 | break 50 | case WorldSource: 51 | v.SourceFlags = bs.GetUnsignedVarInt() 52 | break 53 | } 54 | 55 | IO.InventorySlot = bs.GetUnsignedVarInt() 56 | IO.OldItem = bs.GetVirtualItem() 57 | IO.NewItem = bs.GetVirtualItem() 58 | 59 | return v 60 | } -------------------------------------------------------------------------------- /packets/inventoryio/inventory_action_io_list.go: -------------------------------------------------------------------------------- 1 | package inventoryio 2 | 3 | import ( 4 | "github.com/infinitygamers/goproxy/packets/inventoryio/stream" 5 | ) 6 | 7 | type InventoryActionIOList struct { 8 | List []InventoryActionIO 9 | } 10 | 11 | func NewInventoryActionIOList() *InventoryActionIOList{ 12 | return &InventoryActionIOList{} 13 | } 14 | 15 | func (IOList *InventoryActionIOList) GetCount() int { 16 | return len(IOList.List) 17 | } 18 | 19 | func (IOList *InventoryActionIOList) PutAction(io InventoryActionIO) { 20 | IOList.List = append(IOList.List, io) 21 | } 22 | 23 | func (IOList *InventoryActionIOList) WriteToBuffer(bs *stream.InventoryActionStream) { 24 | c := len(IOList.List) 25 | bs.PutUnsignedVarInt(uint32(c)) 26 | for i := 0; i < c; i++ { 27 | IOList.List[i].WriteToBuffer(bs) 28 | } 29 | } 30 | 31 | func (IOList *InventoryActionIOList) ReadFromBuffer(bs *stream.InventoryActionStream) *InventoryActionIOList{ 32 | c := bs.GetUnsignedVarInt() 33 | for i := uint32(0); i < c; i ++{ 34 | a := NewInventoryActionIO() 35 | a.ReadFromBuffer(bs) 36 | IOList.PutAction(a) 37 | } 38 | return IOList 39 | } -------------------------------------------------------------------------------- /packets/inventoryio/stream/inventory_action_stream.go: -------------------------------------------------------------------------------- 1 | package stream 2 | 3 | import ( 4 | "github.com/irmine/binutils" 5 | ) 6 | 7 | type VirtualItem struct { 8 | Id int32 9 | Damage int32 10 | Count int32 11 | Nbt string 12 | } 13 | 14 | type InventoryActionStream struct { 15 | *binutils.Stream 16 | } 17 | 18 | func NewInventoryActionStream(stream *binutils.Stream) *InventoryActionStream { 19 | return &InventoryActionStream{stream} 20 | } 21 | 22 | func (pk *InventoryActionStream) PutVirtualItem(item *VirtualItem) { 23 | pk.PutVarInt(item.Id) 24 | pk.PutVarInt(((item.Damage & 0x7fff) << 8) | item.Count) 25 | pk.PutLittleShort(int16(len(item.Nbt))) 26 | pk.PutString(item.Nbt) 27 | pk.PutVarInt(0) //todo 28 | pk.PutVarInt(0) //todo 29 | } 30 | 31 | func (pk *InventoryActionStream) GetVirtualItem() *VirtualItem { 32 | id := pk.GetVarInt() 33 | 34 | if id == 0 { 35 | return &VirtualItem{Id: 0, Damage: 0, Count: 0, Nbt: ""} 36 | } 37 | 38 | aux := pk.GetVarInt() 39 | data := aux >> 8 40 | 41 | if data == 0x7fff { 42 | data = -1 43 | } 44 | 45 | count := aux & 0xff 46 | 47 | nbtLen := pk.GetLittleShort() 48 | nbt := "" 49 | if nbtLen > 0 { 50 | //nbt = string(pk.Get(int(nbtLen))) //todo 51 | } 52 | 53 | return &VirtualItem{Id: id, Damage: data, Count: count, Nbt: nbt} 54 | } -------------------------------------------------------------------------------- /packets/modal_form_request_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | type ModalFormRequestPacket struct { 9 | *packets.Packet 10 | FormId uint32 11 | FormData string 12 | } 13 | 14 | func NewModalFormRequestPacket() *ModalFormRequestPacket { 15 | return &ModalFormRequestPacket{packets.NewPacket(info.ModalFormRequestPacket), 0, ""} 16 | } 17 | 18 | func (pk *ModalFormRequestPacket) Encode() { 19 | pk.PutUnsignedVarInt(pk.FormId) 20 | pk.PutString(pk.FormData) 21 | } 22 | 23 | func (pk *ModalFormRequestPacket) Decode() { 24 | pk.FormId = pk.GetUnsignedVarInt() 25 | pk.FormData = pk.GetString() 26 | } -------------------------------------------------------------------------------- /packets/modal_form_response_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | type ModalFormResponsePacket struct { 9 | *packets.Packet 10 | FormId uint32 11 | FormData string 12 | } 13 | 14 | func NewModalFormResponsePacket() *ModalFormResponsePacket { 15 | return &ModalFormResponsePacket{packets.NewPacket(info.ModalFormResponsePacket), 0, ""} 16 | } 17 | 18 | func (pk *ModalFormResponsePacket) Encode() { 19 | pk.PutUnsignedVarInt(pk.FormId) 20 | pk.PutString(pk.FormData) 21 | } 22 | 23 | func (pk *ModalFormResponsePacket) Decode() { 24 | pk.FormId = pk.GetUnsignedVarInt() 25 | pk.FormData = pk.GetString() 26 | } -------------------------------------------------------------------------------- /packets/move_entity_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/golang/geo/r3" 5 | "github.com/irmine/gomine/net/info" 6 | "github.com/Irmine/GoMine/net/packets" 7 | data2 "github.com/irmine/worlds/entities/data" 8 | ) 9 | 10 | type MoveEntityPacket struct { 11 | *packets.Packet 12 | RuntimeId uint64 13 | Position r3.Vector 14 | Rotation data2.Rotation 15 | Mode byte 16 | OnGround bool 17 | Teleported bool 18 | } 19 | 20 | func NewMoveEntityPacket() *MoveEntityPacket { 21 | return &MoveEntityPacket{Packet: packets.NewPacket(info.PacketIds200[info.MoveEntityPacket]), Position: r3.Vector{}, Rotation: data2.Rotation{}} 22 | } 23 | 24 | func (pk *MoveEntityPacket) Encode() { 25 | pk.PutEntityRuntimeId(pk.RuntimeId) 26 | pk.PutVector(pk.Position) 27 | pk.PutEntityRotation(pk.Rotation) 28 | pk.PutByte(pk.Mode) 29 | pk.PutBool(pk.OnGround) 30 | pk.PutBool(pk.Teleported) 31 | } 32 | 33 | func (pk *MoveEntityPacket) Decode() { 34 | pk.RuntimeId = pk.GetEntityRuntimeId() 35 | pk.Position = pk.GetVector() 36 | pk.Rotation = pk.GetEntityRotation() 37 | pk.Mode = pk.GetByte() 38 | pk.OnGround = pk.GetBool() 39 | pk.Teleported = pk.GetBool() 40 | } 41 | -------------------------------------------------------------------------------- /packets/move_player_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/golang/geo/r3" 5 | "github.com/irmine/gomine/net/info" 6 | "github.com/Irmine/GoMine/net/packets" 7 | "github.com/irmine/gomine/net/packets/data" 8 | data2 "github.com/irmine/worlds/entities/data" 9 | ) 10 | 11 | type MovePlayerPacket struct { 12 | *packets.Packet 13 | RuntimeId uint64 14 | Position r3.Vector 15 | Rotation data2.Rotation 16 | Mode byte 17 | OnGround bool 18 | RidingRuntimeId uint64 19 | ExtraInt1, ExtraInt2 int32 20 | } 21 | 22 | func NewMovePlayerPacket() *MovePlayerPacket { 23 | return &MovePlayerPacket{Packet: packets.NewPacket(info.PacketIds200[info.MovePlayerPacket]), Position: r3.Vector{}, Rotation: data2.Rotation{}} 24 | } 25 | 26 | func (pk *MovePlayerPacket) Encode() { 27 | pk.PutEntityRuntimeId(pk.RuntimeId) 28 | pk.PutVector(pk.Position) 29 | pk.PutPlayerRotation(pk.Rotation) 30 | pk.PutByte(pk.Mode) 31 | pk.PutBool(pk.OnGround) 32 | pk.PutEntityRuntimeId(pk.RidingRuntimeId) 33 | if pk.Mode == data.MoveTeleport { 34 | pk.PutLittleInt(pk.ExtraInt1) 35 | pk.PutLittleInt(pk.ExtraInt2) 36 | } 37 | } 38 | 39 | func (pk *MovePlayerPacket) Decode() { 40 | pk.RuntimeId = pk.GetEntityRuntimeId() 41 | pk.Position = pk.GetVector() 42 | pk.Rotation = pk.GetPlayerRotation() 43 | pk.Mode = pk.GetByte() 44 | pk.OnGround = pk.GetBool() 45 | pk.RidingRuntimeId = pk.GetEntityRuntimeId() 46 | if pk.Mode == data.MoveTeleport { 47 | pk.ExtraInt1 = pk.GetLittleInt() 48 | pk.ExtraInt2 = pk.GetLittleInt() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packets/remove_entity_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | type RemoveEntityPacket struct { 9 | *packets.Packet 10 | RuntimeId uint64 11 | } 12 | 13 | func NewRemoveEntityPacket() *RemoveEntityPacket { 14 | return &RemoveEntityPacket{packets.NewPacket(info.RemoveEntityPacket), 0} 15 | } 16 | 17 | func (pk *RemoveEntityPacket) Encode() { 18 | pk.PutEntityRuntimeId(pk.RuntimeId) 19 | } 20 | 21 | func (pk *RemoveEntityPacket) Decode() { 22 | pk.RuntimeId = pk.GetEntityRuntimeId() 23 | } 24 | -------------------------------------------------------------------------------- /packets/set_game_mode_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | type SetGameModePacket struct { 9 | *packets.Packet 10 | GameMode int32 11 | } 12 | 13 | func NewSetGamemodePacket() *SetGameModePacket { 14 | return &SetGameModePacket{ packets.NewPacket(info.SetPlayerGameTypePacket), 0} 15 | } 16 | 17 | func (pk *SetGameModePacket) Encode() { 18 | pk.PutVarInt(pk.GameMode) 19 | } 20 | 21 | func (pk *SetGameModePacket) Decode() { 22 | pk.GameMode = pk.GetVarInt() 23 | } -------------------------------------------------------------------------------- /packets/set_title_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | const ( 9 | ClearTitle = iota 10 | ResetTitle 11 | SetTitle 12 | SetSubtitle 13 | SetActionBarMessage 14 | SetAnimationTimes 15 | ) 16 | 17 | type SetTitlePacket struct { 18 | *packets.Packet 19 | TitleType int32 20 | Text string 21 | FadeInTime int32 22 | StayTime int32 23 | FadeOutTime int32 24 | } 25 | 26 | func NewSetTitlePacket() *SetTitlePacket { 27 | return &SetTitlePacket{ 28 | packets.NewPacket(info.SetTitlePacket), 29 | 0, 30 | "", 31 | 0, 32 | 0, 33 | 0, 34 | } 35 | } 36 | 37 | func (pk *SetTitlePacket) Encode() { 38 | pk.PutVarInt(pk.TitleType) 39 | pk.PutString(pk.Text) 40 | pk.PutVarInt(pk.FadeInTime) 41 | pk.PutVarInt(pk.StayTime) 42 | pk.PutVarInt(pk.FadeOutTime) 43 | } 44 | 45 | func (pk *SetTitlePacket) Decode() { 46 | pk.TitleType = pk.GetVarInt() 47 | pk.Text = pk.GetString() 48 | pk.FadeInTime = pk.GetVarInt() 49 | pk.StayTime = pk.GetVarInt() 50 | pk.FadeOutTime = pk.GetVarInt() 51 | } -------------------------------------------------------------------------------- /packets/text_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/infinitygamers/goproxy/info" 6 | ) 7 | 8 | const ( 9 | Raw = 0x00 10 | Chat = 0x01 11 | Translation = 0x02 12 | Popup = 0x03 13 | JukeboxPopup = 0x04 14 | Tip = 0x05 15 | System = 0x06 16 | Whisper = 0x07 17 | Announcement = 0x08 18 | ) 19 | 20 | type TextPacket struct { 21 | *packets.Packet 22 | TextType byte 23 | Translation bool 24 | Source string 25 | SourceThirdParty string 26 | SourcePlatform int32 27 | Message string 28 | Xuid string 29 | PlatformChatId string 30 | 31 | Params []string 32 | } 33 | 34 | func NewTextPacket() *TextPacket { 35 | return &TextPacket{ 36 | packets.NewPacket(info.TextPacket), 37 | Raw, 38 | false, 39 | "", 40 | "", 41 | 0, 42 | "", 43 | "", 44 | "", 45 | []string{}, 46 | } 47 | } 48 | 49 | func (pk *TextPacket) Encode() { 50 | pk.PutByte(pk.TextType) 51 | pk.PutBool(pk.Translation) 52 | 53 | switch pk.TextType { 54 | case Raw, Tip, System: 55 | pk.PutString(pk.Message) 56 | break 57 | case Chat, Whisper, Announcement: 58 | pk.PutString(pk.Source) 59 | pk.PutString(pk.SourceThirdParty) 60 | pk.PutVarInt(pk.SourcePlatform) 61 | pk.PutString(pk.Message) 62 | break 63 | case Translation, Popup, JukeboxPopup: 64 | pk.PutString(pk.Message) 65 | pk.PutUnsignedVarInt(uint32(len(pk.Params))) 66 | for _, v := range pk.Params { 67 | pk.PutString(v) 68 | } 69 | break 70 | } 71 | 72 | pk.PutString(pk.Xuid) 73 | pk.PutString(pk.PlatformChatId) 74 | } 75 | 76 | func (pk *TextPacket) Decode() { 77 | pk.TextType = pk.GetByte() 78 | pk.Translation = pk.GetBool() 79 | 80 | switch pk.TextType { 81 | case Raw, Tip, System: 82 | pk.Message = pk.GetString() 83 | break 84 | case Chat, Whisper, Announcement: 85 | pk.Source = pk.GetString() 86 | pk.SourceThirdParty = pk.GetString() 87 | pk.SourcePlatform = pk.GetVarInt() 88 | pk.Message = pk.GetString() 89 | break 90 | case Translation, Popup, JukeboxPopup: 91 | pk.Message = pk.GetString() 92 | c := pk.GetUnsignedVarInt() 93 | for i := uint32(0); i < c; i++ { 94 | pk.Params = append(pk.Params, pk.GetString()) 95 | } 96 | break 97 | } 98 | 99 | pk.Xuid = pk.GetString() 100 | pk.PlatformChatId = pk.GetString() 101 | } -------------------------------------------------------------------------------- /packets/update_attributes_packet.go: -------------------------------------------------------------------------------- 1 | package packets 2 | 3 | import ( 4 | "github.com/Irmine/GoMine/net/packets" 5 | "github.com/irmine/worlds/entities/data" 6 | info2 "github.com/infinitygamers/goproxy/info" 7 | ) 8 | 9 | type UpdateAttributesPacket struct { 10 | *packets.Packet 11 | RuntimeId uint64 12 | Attributes data.AttributeMap 13 | } 14 | 15 | func NewUpdateAttributesPacket() *UpdateAttributesPacket { 16 | return &UpdateAttributesPacket{packets.NewPacket(info2.UpdateAttributesPacket), 0, data.NewAttributeMap()} 17 | } 18 | 19 | func (pk *UpdateAttributesPacket) Encode() { 20 | pk.PutEntityRuntimeId(pk.RuntimeId) 21 | pk.PutAttributeMap(pk.Attributes) 22 | } 23 | 24 | func (pk *UpdateAttributesPacket) Decode() { 25 | pk.RuntimeId = pk.GetEntityRuntimeId() 26 | pk.Attributes = pk.GetAttributeMap() 27 | } 28 | -------------------------------------------------------------------------------- /proxy.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "net" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | type Proxy struct { 10 | *net.UDPConn 11 | Config Config 12 | } 13 | 14 | const ( 15 | Prefix = "GoProxy > " 16 | Author = "xBeastMode" 17 | Version = "1.2" 18 | ) 19 | 20 | var LogoType = []string{ 21 | " _____ _____", 22 | " / ____| | __ \\", 23 | "| | __ ___ | |__) | __ _____ ___ _ ", 24 | "| | |_ |/ _ \\| ___/ '__/ _ \\ \\/ / | | |", 25 | "| |__| | (_) | | | | | (_) > <| |_| |", 26 | " \\_____|\\___/|_| |_| \\___/_/\\_\\\\__, |", 27 | " __/ |", 28 | " |___/ ", 29 | } 30 | 31 | // this function starts the Proxy 32 | // it will start "sniffing" packets 33 | func StartProxy() { 34 | var config = NewConfig() 35 | var proxy = Proxy{Config:config} 36 | var err error 37 | 38 | // forward the Proxy to a custom port 39 | proxy.UDPConn, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP(config.BindAddr), Port: config.BindPort}) 40 | 41 | if err != nil { 42 | Panic(err.Error()) 43 | os.Exit(1) 44 | } 45 | 46 | // just typical console logs 47 | for _, v := range LogoType { 48 | Info(AnsiBrightRed + v) 49 | } 50 | Info(AnsiGreen + Author + "'s Proxy version " + Version) 51 | Info("Starting Proxy on " + config.BindAddr + ":" + strconv.Itoa(config.BindPort)) 52 | 53 | if err != nil { 54 | Panic(err.Error()) 55 | os.Exit(1) 56 | } 57 | 58 | // looks up the Server domain and returns it address 59 | addrs, err := net.LookupHost(config.ServerAddr) 60 | 61 | if err != nil { 62 | Panic(err.Error()) 63 | os.Exit(1) 64 | } 65 | 66 | // resolve Server address 67 | addr, err := net.ResolveUDPAddr("udp", addrs[0] + ":" + strconv.Itoa(config.ServerPort)) 68 | 69 | if err != nil { 70 | Panic(err.Error()) 71 | os.Exit(1) 72 | } 73 | 74 | // start a new Connection between Server and Client 75 | conn := NewConnection(&proxy) 76 | conn.Server.SetAddress(addr) 77 | 78 | Info("Listening to Server address: " + addrs[0] + ":" + strconv.Itoa(config.ServerPort)) 79 | 80 | // start the packet "sniffing" from Client 81 | conn.HandleIncomingPackets() 82 | } -------------------------------------------------------------------------------- /reliability.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | const ( 4 | Unreliable = iota + 0x00 5 | UnreliableSequenced 6 | Reliable 7 | ReliableOrdered 8 | ReliableSequenced 9 | UnreliableWithAckReceipt 10 | ReliableWithAckReceipt 11 | ReliableOrderedWithAckReceipt 12 | ) 13 | 14 | func isReliable(reliability byte) bool { 15 | return reliability == Reliable || reliability == ReliableOrdered || reliability == ReliableSequenced || reliability == ReliableWithAckReceipt || reliability == ReliableOrderedWithAckReceipt 16 | } 17 | 18 | func isSequenced(reliability byte) bool { 19 | return reliability == UnreliableSequenced || reliability == ReliableSequenced 20 | } 21 | 22 | func isOrdered(reliability byte) bool { 23 | return reliability == ReliableOrdered || reliability == ReliableOrderedWithAckReceipt 24 | } 25 | 26 | func isSequencedOrdered(reliability byte) bool { 27 | return reliability == UnreliableSequenced || reliability == ReliableOrdered || reliability == ReliableSequenced || reliability == ReliableOrderedWithAckReceipt 28 | } -------------------------------------------------------------------------------- /server.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "net" 5 | "github.com/Irmine/GoMine/net/packets" 6 | ) 7 | 8 | type Server struct { 9 | Host // Server extends a host that has writable packets 10 | // Server's udp address 11 | addr *net.UDPAddr 12 | // the main Proxy 13 | Proxy *Proxy 14 | // the Connection between the Server 15 | // and the Client 16 | Conn *Connection 17 | // Server Data contains the Server's query info such as: 18 | // Server name, version, protocol, players, software, etc... 19 | Data ServerData 20 | // the Server's uid 21 | serverId int64 22 | } 23 | 24 | 25 | // returns new Server host 26 | // that has writable packets 27 | func NewServer(proxy *Proxy, conn *Connection) *Server { 28 | server := Server{} 29 | server.Proxy = proxy 30 | server.Conn = conn 31 | server.Data = NewServerData() 32 | return &server 33 | } 34 | 35 | // returns if this host is the client 36 | // this is the server struct to it returns false 37 | func (server Server) IsClient() bool { 38 | return false 39 | } 40 | 41 | // returns if this host is the client 42 | // this is the server struct to it returns true 43 | func (server Server) IsServer() bool { 44 | return true 45 | } 46 | 47 | // this function is from the host interface 48 | // it writes a packet buffer to the Server 49 | func (server Server) WritePacket(buffer []byte) { 50 | _, err := server.Proxy.WriteToUDP(buffer, server.addr) 51 | if err != nil { 52 | Alert(err.Error()) 53 | } 54 | } 55 | 56 | // this function is from the host interface 57 | // it sends a single packet 58 | func (server Server) SendPacket(packet packets.IPacket) { 59 | server.SendBatchPacket([]packets.IPacket{packet}) 60 | } 61 | 62 | // this function is from the host interface 63 | // it sends a batch packet: 64 | // a packet with multiple packets inside 65 | func (server Server) SendBatchPacket(packets []packets.IPacket) { 66 | datagram := server.Conn.pkHandler.DatagramBuilder.BuildFromPackets(packets) 67 | server.WritePacket(datagram.Buffer) 68 | } 69 | 70 | // this set's the udp address 71 | // which is used to communicate with the Server 72 | func (server *Server) SetAddress(addr *net.UDPAddr) { 73 | server.addr = addr 74 | } 75 | 76 | // returns the Server's address as net.UDPAddr 77 | func (server Server) GetAddress() net.UDPAddr { 78 | return *server.addr 79 | } 80 | 81 | // this returns the Server's Data struct 82 | func (server *Server) GetServerData() ServerData { 83 | return server.GetServerData() 84 | } -------------------------------------------------------------------------------- /server_data.go: -------------------------------------------------------------------------------- 1 | package goproxy 2 | 3 | import ( 4 | "strings" 5 | "strconv" 6 | ) 7 | 8 | // this struct holds the Server Data 9 | type ServerData struct { 10 | // raw Server Data as mixed slice 11 | RawData []interface{} 12 | // Server name as string 13 | serverName string 14 | // Server protocol version as int 15 | protocolVersion int 16 | // Server game version as int 17 | gameVersion int 18 | // Server online player count as int 19 | onlinePlayerCount int //ignore 20 | // Server nax player count as int 21 | maxPlayerCount int //ignore 22 | } 23 | 24 | func NewServerData() ServerData { 25 | return ServerData{} 26 | } 27 | 28 | // This parses Data sent from the Server 29 | // the Data is send in this format: 30 | // MCPE;Server name;protocol version;MCPE version;online player count;max player count 31 | func (svData *ServerData) ParseFromString(data string){ 32 | split := strings.Split(data, ";")[1:] 33 | svData.serverName = split[0] 34 | svData.protocolVersion, _ = strconv.Atoi(split[1]) 35 | svData.gameVersion, _ = strconv.Atoi(split[2]) 36 | svData.onlinePlayerCount, _ = strconv.Atoi(split[3]) 37 | svData.maxPlayerCount, _ = strconv.Atoi(split[4]) 38 | } 39 | 40 | // returns the Server name sent from the Server 41 | func (svData *ServerData) GetServerName() string { 42 | return svData.serverName 43 | } 44 | 45 | // returns the protocol version sent from the Server 46 | func (svData *ServerData) GetProtocolVersion() int { 47 | return svData.protocolVersion 48 | } 49 | 50 | // returns the game version sent from the Server 51 | func (svData *ServerData) GetGameVersion() int { 52 | return svData.gameVersion 53 | } -------------------------------------------------------------------------------- /start/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/infinitygamers/goproxy" 5 | ) 6 | 7 | func main() { 8 | mcpeproxy.StartProxy() 9 | } 10 | --------------------------------------------------------------------------------