summaryrefslogblamecommitdiffstats
path: root/src/Packet.hpp
blob: e00f1ed67b1b0b34455b78148379760d72a31c8c (plain) (tree)
1
2
3
4
5
6
7
8
9

            
                     





                                  
                               



















































































                                  
                 














































































































































                                                          
                                                                           














                                                        
                                                
















































                                                                        






                                                







































































                                                                         





                                              




















                                                                                                                  






                                                          
                                                                   






                                                        
                                                
                                                   



                                                                                  









                                                   
                   
                                        

                                                                                             










                                                       



                                              





















                                                                                                                   


                                              














                                                                                                           


                                                   














                                                       


































                                                   

































                                                    
                    
                                    
                                    
                                        






























































































































































                                                           

















































                                                            

















                                                   

















                                                   




























































































































































































                                                                                                                                                                   
 
#pragma once

#include "Stream.hpp"

enum PacketNameLoginSB {
	LoginStart = 0x00,
	EncryptionResponse = 0x01,
};
enum PacketNamePlaySB {
	TeleportConfirm = 0x00,
	PrepareCraftingGrid,
	TabCompleteSB,
	ChatMessageSB,
	ClientStatus,
	ClientSettings,
	ConfirmTransactionSB,
	EnchantItem,
	ClickWindow,
	CloseWindowSB,
	PluginMessageSB,
	UseEntity,
	KeepAliveSB,
	Player,
	PlayerPosition,
	PlayerPositionAndLookSB,
	PlayerLook,
	VehicleMoveSB,
	SteerBoat,
	PlayerAbilitiesSB,
	PlayerDigging,
	EntityAction,
	SteerVehicle,
	CraftingBookData,
	ResourcePackStatus,
	AdvancementTab,
	HeldItemChangeSB,
	CreativeInventoryAction,
	UpdateSign,
	AnimationSB,
	Spectate,
	PlayerBlockPlacement,
	UseItem,
};

enum PacketNameHandshakingCB {
	Handshake = 0x00,
};
enum PacketNameLoginCB {
	Disconnect = 0x00,
	EncryptionRequest = 0x01,
	LoginSuccess = 0x02,
	SetCompression = 0x03,
};
enum PacketNamePlayCB {
	SpawnObject = 0x00,
	SpawnExperienceOrb,
	SpawnGlobalEntity,
	SpawnMob,
	SpawnPainting,
	SpawnPlayer,
	AnimationCB,
	Statistics,
	BlockBreakAnimation,
	UpdateBlockEntity,
	BlockAction,
	BlockChange,
	BossBar,
	ServerDifficulty,
	TabCompleteCB,
	ChatMessageCB,
	MultiBlockChange,
	ConfirmTransactionCB,
	CloseWindowCB,
	OpenWindow,
	WindowItems,
	WindowProperty,
	SetSlot,
	SetCooldown,
	PluginMessageCB,
	NamedSoundEffect,
	DisconnectPlay,
	EntityStatus,
	Explosion,
	UnloadChunk,
	ChangeGameState,
	KeepAliveCB,
	ChunkData,
	Effect,
	Particle,
	JoinGame,
	Map,
	EntityRelativeMove,
	EntityLookAndRelativeMove,
	EntityLook,
	EntityCB,
	VehicleMove,
	OpenSignEditor,
	PlayerAbilitiesCB,
	CombatEvent,
	PlayerListItem,
	PlayerPositionAndLookCB,
	UseBed,
	UnlockRecipes,
	DestroyEntities,
	RemoveEntityEffect,
	ResourcePackSend,
	Respawn,
	EntityHeadLook,
	SelectAdvancementTab,
	WorldBorder,
	Camera,
	HeldItemChangeCB,
	DisplayScoreboard,
	EntityMetadata,
	AttachEntity,
	EntityVelocity,
	EntityEquipment,
	SetExperience,
	UpdateHealth,
	ScoreboardObjective,
	SetPassengers,
	Teams,
	UpdateScore,
	SpawnPosition,
	TimeUpdate,
	Title,
	SoundEffect,
	PlayerListHeaderAndFooter,
	CollectItem,
	EntityTeleport,
	Advancements,
	EntityProperties,
	EntityEffect,
};

struct Packet {
	virtual ~Packet() = default;
	virtual void ToStream(StreamOutput *stream) = 0;
	virtual void FromStream(StreamInput *stream) = 0;
	virtual int GetPacketId() = 0;
};

struct PacketHandshake : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteVarInt(protocolVersion);
		stream->WriteString(serverAddress);
		stream->WriteUShort(serverPort);
		stream->WriteVarInt(nextState);
	}

	void FromStream(StreamInput *stream) override {
		protocolVersion = stream->ReadVarInt();
		serverAddress = stream->ReadString();
		serverPort = stream->ReadUShort();
		nextState = stream->ReadVarInt();
	}

	int GetPacketId() override {
		return PacketNameHandshakingCB::Handshake;
	}

	int protocolVersion;
	std::string serverAddress;
	unsigned short serverPort;
	int nextState;
};

struct PacketLoginStart : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteString(Username);
	}

	void FromStream(StreamInput *stream) override {
		Username = stream->ReadString();
	}

	int GetPacketId() override {
		return PacketNameLoginSB::LoginStart;
	}

	std::string Username;
};

struct PacketLoginSuccess : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteString(Uuid);
		stream->WriteString(Username);
	}

	void FromStream(StreamInput *stream) override {
		Uuid = stream->ReadString();
		Username = stream->ReadString();
	}

	int GetPacketId() override {
		return PacketNameLoginCB::LoginSuccess;
	}

	std::string Uuid;
	std::string Username;
};

struct PacketJoinGame : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteInt(EntityId);
		stream->WriteUByte(Gamemode);
		stream->WriteInt(Dimension);
		stream->WriteUByte(Difficulty);
		stream->WriteUByte(MaxPlayers);
		stream->WriteString(LevelType);
		stream->WriteBool(ReducedDebugInfo);
	}

	void FromStream(StreamInput *stream) override {
		EntityId = stream->ReadInt();
		Gamemode = stream->ReadUByte();
		Dimension = stream->ReadInt();
		Difficulty = stream->ReadUByte();
		MaxPlayers = stream->ReadUByte();
		LevelType = stream->ReadString();
		ReducedDebugInfo = stream->ReadBool();
	}

	int GetPacketId() override {
		return PacketNamePlayCB::JoinGame;
	}

	int EntityId;
	unsigned char Gamemode;
	int Dimension;
	unsigned char Difficulty;
	unsigned char MaxPlayers;
	std::string LevelType;
	bool ReducedDebugInfo;
};

struct PacketDisconnectPlay : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteString(Reason); //TODO: Implement chat-wrapper
	}

	void FromStream(StreamInput *stream) override {
		Reason = stream->ReadChat();
	}

	int GetPacketId() override {
		return PacketNamePlayCB::DisconnectPlay;
	}

	std::string Reason;
};

struct PacketSpawnPosition : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WritePosition(Location);
	}

	void FromStream(StreamInput *stream) override {
		Location = stream->ReadPosition();
	}

	int GetPacketId() override {
		return PacketNamePlayCB::SpawnPosition;
	}

	Vector Location;
};

struct PacketKeepAliveCB : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteVarInt(KeepAliveId);
	}

	void FromStream(StreamInput *stream) override {
		KeepAliveId = stream->ReadVarInt();
	}

	int GetPacketId() override {
		return PacketNamePlayCB::KeepAliveCB;
	}

	int KeepAliveId;
};

struct PacketKeepAliveSB : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteVarInt(KeepAliveId);
	}

	void FromStream(StreamInput *stream) override {
		KeepAliveId = stream->ReadVarInt();
	}

	int GetPacketId() override {
		return PacketNamePlaySB::KeepAliveSB;
	}

	int KeepAliveId;

	PacketKeepAliveSB(int KeepAliveId) : KeepAliveId(KeepAliveId) {}
};

struct PacketPlayerPositionAndLookCB : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteDouble(X);
		stream->WriteDouble(Y);
		stream->WriteDouble(Z);
		stream->WriteFloat(Yaw);
		stream->WriteFloat(Pitch);
		stream->WriteUByte(Flags);
		stream->WriteVarInt(TeleportId);
	}

	void FromStream(StreamInput *stream) override {
		X = stream->ReadDouble();
		Y = stream->ReadDouble();
		Z = stream->ReadDouble();
		Yaw = stream->ReadFloat();
		Pitch = stream->ReadFloat();
		Flags = stream->ReadUByte();
		TeleportId = stream->ReadVarInt();
	}

	int GetPacketId() override {
		return PacketNamePlayCB::PlayerPositionAndLookCB;
	}

	double X;
	double Y;
	double Z;
	float Yaw;
	float Pitch;
	unsigned char Flags;
	int TeleportId;
};

struct PacketTeleportConfirm : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteVarInt(TeleportId);
	}

	void FromStream(StreamInput *stream) override {
		TeleportId = stream->ReadVarInt();
	}

	int GetPacketId() override {
		return PacketNamePlaySB::TeleportConfirm;
	}

	int TeleportId;

	PacketTeleportConfirm(int TeleportId) : TeleportId(TeleportId) {}
};

struct PacketClientStatus : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteVarInt(ActionId);
	}

	void FromStream(StreamInput *stream) override {
		ActionId = stream->ReadVarInt();
	}

	int GetPacketId() override {
		return PacketNamePlaySB::ClientStatus;
	}

	int ActionId;

	PacketClientStatus(int ActionId) : ActionId(ActionId) {}
};

struct PacketPlayerPositionAndLookSB : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteDouble(X);
		stream->WriteDouble(FeetY);
		stream->WriteDouble(Z);
		stream->WriteFloat(Yaw);
		stream->WriteFloat(Pitch);
		stream->WriteBool(OnGround);
	}

	void FromStream(StreamInput *stream) override {
		X = stream->ReadDouble();
		FeetY = stream->ReadDouble();
		Z = stream->ReadDouble();
		Yaw = stream->ReadFloat();
		Pitch = stream->ReadFloat();
		OnGround = stream->ReadBool();
	}

	int GetPacketId() override {
		return PacketNamePlaySB::PlayerPositionAndLookSB;
	}


	double X;
	double FeetY;
	double Z;
	float Yaw;
	float Pitch;
	bool OnGround;

	PacketPlayerPositionAndLookSB(double X, double FeetY, double Z,
	                              float Yaw, float Pitch, bool OnGround) : X(X), FeetY(FeetY), Z(Z), Yaw(Yaw),
	                                                                       Pitch(Pitch), OnGround(OnGround) {}
};

struct PacketChunkData : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteInt(ChunkX);
		stream->WriteInt(ChunkZ);
		stream->WriteBool(GroundUpContinuous);
		stream->WriteInt(PrimaryBitMask);
		stream->WriteVarInt(Data.size());
		stream->WriteByteArray(Data);
		stream->WriteVarInt(BlockEntities.size());
		//LOG(FATAL) << "Serializing unimplemented packet";
	}

	void FromStream(StreamInput *stream) override {
		ChunkX = stream->ReadInt();
		ChunkZ = stream->ReadInt();
		GroundUpContinuous = stream->ReadBool();
		PrimaryBitMask = stream->ReadVarInt();
		int Size = stream->ReadVarInt();
		Data = stream->ReadByteArray(Size);
		int NumberOfBlockEntities = stream->ReadVarInt(); //TODO: Need NBT
		for (int i = 0; i < NumberOfBlockEntities; i++) {
			//BlockEntities[i] = stream->ReadNbt();
		}
	}

	int GetPacketId() override {
		return PacketNamePlayCB::ChunkData;
	}

	int ChunkX;
	int ChunkZ;
	bool GroundUpContinuous;
	int PrimaryBitMask;
	//int Size;
	std::vector<unsigned char> Data;
	//int NumberOfBlockEntities;
	std::vector<int> BlockEntities; //TODO: Replace int with NbtTag and implement NbtTree
};

struct PacketPlayerPosition : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteDouble(X);
		stream->WriteDouble(FeetY);
		stream->WriteDouble(Z);
		stream->WriteBool(OnGround);
	}

	void FromStream(StreamInput *stream) override {
		X = stream->ReadDouble();
		FeetY = stream->ReadDouble();
		Z = stream->ReadDouble();
		OnGround = stream->ReadBool();
	}

	int GetPacketId() override {
		return PacketNamePlaySB::PlayerPosition;
	}

	double X;
	double FeetY;
	double Z;
	bool OnGround;

	PacketPlayerPosition(double X, double Y, double Z, bool ground) : X(X), FeetY(Y), Z(Z), OnGround(ground) {}
};

struct PacketPlayerLook : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteFloat(Yaw);
		stream->WriteFloat(Pitch);
		stream->WriteBool(OnGround);
	}

	void FromStream(StreamInput *stream) override {
		Yaw = stream->ReadFloat();
		Pitch = stream->ReadFloat();
		OnGround = stream->ReadBool();
	}

	int GetPacketId() override {
		return PacketNamePlaySB::PlayerLook;
	}

	float Yaw;
	float Pitch;
	bool OnGround;

	PacketPlayerLook(float Yaw, float Pitch, bool ground) : Yaw(Yaw), Pitch(Pitch), OnGround(ground) {}
};

struct PacketUpdateHealth : Packet {
	void ToStream(StreamOutput *stream) override {
		stream->WriteFloat(Health);
		stream->WriteVarInt(Food);
		stream->WriteFloat(FoodSaturation);
	}

	void FromStream(StreamInput *stream) override {
		Health = stream->ReadFloat();
		Food = stream->ReadVarInt();
		FoodSaturation = stream->ReadFloat();
	}

	int GetPacketId() override {
		return PacketNamePlayCB::UpdateHealth;
	}

	float Health;
	int Food;
	float FoodSaturation;
};

struct PacketSpawnObject : Packet {
    void ToStream(StreamOutput *stream) override {
        
    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        ObjectUuid = stream->ReadUuid();
        Type = stream->ReadByte();
        X = stream->ReadDouble();
        Y = stream->ReadDouble();
        Z = stream->ReadDouble();
        Pitch = stream->ReadAngle();
        Yaw = stream->ReadAngle();
        Data = stream->ReadInt();
        VelocityX = stream->ReadShort();
        VelocityY = stream->ReadShort();
        VelocityZ = stream->ReadShort();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::SpawnObject;
    }

    int EntityId;
    Uuid ObjectUuid;
    unsigned char Type;    
    double X, Y, Z;
    unsigned char Pitch, Yaw;
    int Data;
    short VelocityX;
    short VelocityY;
    short VelocityZ;
};

struct PacketEntityRelativeMove : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        DeltaX = stream->ReadShort();
        DeltaY = stream->ReadShort();
        DeltaZ = stream->ReadShort();
        OnGround = stream->ReadBool();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::EntityRelativeMove;
    }

    int EntityId;
    short DeltaX, DeltaY, DeltaZ;
    bool OnGround;
};

struct PacketEntityLookAndRelativeMove : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        DeltaX = stream->ReadShort();
        DeltaY = stream->ReadShort();
        DeltaZ = stream->ReadShort();
        //TODO: WTF?
        /*Yaw = stream->ReadAngle();
        Pitch = stream->ReadAngle();
        OnGround = stream->ReadBool();*/
    }

    int GetPacketId() override {
        return PacketNamePlayCB::EntityLookAndRelativeMove;
    }

    int EntityId;
    short DeltaX, DeltaY, DeltaZ;
    unsigned char Yaw, Pitch;
    bool OnGround;
};

struct PacketEntityLook : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        Yaw = stream->ReadAngle();
        Pitch = stream->ReadAngle();
        OnGround = stream->ReadBool();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::EntityLook;
    }

    int EntityId;
    unsigned char Yaw, Pitch;
    bool OnGround;
};

struct PacketEntityVelocity : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        VelocityX = stream->ReadShort();
        VelocityY = stream->ReadShort();
        VelocityZ = stream->ReadShort();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::EntityVelocity;
    }

    int EntityId;
    short VelocityX;
    short VelocityY;
    short VelocityZ;
};

struct PacketEntityTeleport : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        X = stream->ReadDouble();
        Y = stream->ReadDouble();
        Z = stream->ReadDouble();
        Yaw = stream->ReadAngle();
        Pitch = stream->ReadAngle();
        OnGround = stream->ReadBool();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::EntityTeleport;
    }

    int EntityId;
    double X, Y, Z;
    unsigned char Yaw, Pitch;
    bool OnGround;
};

struct PacketSpawnPlayer : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        PlayerUuid = stream->ReadUuid();
        X = stream->ReadDouble();
        Y = stream->ReadDouble();
        Z = stream->ReadDouble();
        Yaw = stream->ReadAngle();
        Pitch = stream->ReadAngle();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::SpawnPlayer;
    }

    int EntityId;
    Uuid PlayerUuid;
    double X, Y, Z;
    unsigned char Yaw, Pitch;
    

};

struct PacketDestroyEntities : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        int count = stream->ReadVarInt();
        EntityIds.reserve(count);
        for (int i = 0; i < count; i++) {
            int entityId = stream->ReadVarInt();
            EntityIds.push_back(entityId);
        }
    }

    int GetPacketId() override {
        return PacketNamePlayCB::DestroyEntities;
    }

    std::vector <unsigned int> EntityIds;
};

struct PacketSpawnMob : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        EntityId = stream->ReadVarInt();
        EntityUuid = stream->ReadUuid();
        type = stream->ReadVarInt();
        X = stream->ReadDouble();
        Y = stream->ReadDouble();
        Z = stream->ReadDouble();
        Yaw = stream->ReadAngle();
        Pitch = stream->ReadAngle();
        HeadPitch = stream->ReadAngle();
        VelocityX = stream->ReadShort();
        VelocityY = stream->ReadShort();
        VelocityZ = stream->ReadShort();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::SpawnMob;
    }

    unsigned int EntityId;
    Uuid EntityUuid;
    int type;
    double X, Y, Z;
    unsigned char Yaw, Pitch, HeadPitch;
    short VelocityX, VelocityY, VelocityZ;
    //Metadata
};

struct PacketBlockChange : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        Position = stream->ReadPosition();
        BlockId = stream->ReadVarInt();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::BlockChange;
    }

    Vector Position;
    int BlockId;
};

struct PacketMultiBlockChange : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        ChunkX = stream->ReadInt();
        ChunkZ = stream->ReadInt();
        int recordCount = stream->ReadVarInt();
        for (int i = 0; i < recordCount; i++) {
            Record record;
            record.HorizontalPosition = stream->ReadUByte();
            record.YCoordinate = stream->ReadUByte();
            record.BlockId = stream->ReadVarInt();
            Records.push_back(record);
        }
    }

    int GetPacketId() override {
        return PacketNamePlayCB::MultiBlockChange;
    }

    int ChunkX;
    int ChunkZ;
    struct Record {
        unsigned char HorizontalPosition;
        unsigned char YCoordinate;
        int BlockId;
    };
    std::vector<Record> Records;
};

struct PacketTimeUpdate : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WorldAge = stream->ReadLong();
        TimeOfDay = stream->ReadLong();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::TimeUpdate;
    }

    long long WorldAge;
    long long TimeOfDay;
};

struct PacketUnloadChunk : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        ChunkX = stream->ReadInt();
        ChunkZ = stream->ReadInt();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::UnloadChunk;
    }

    int ChunkX;
    int ChunkZ;
};

struct PacketCloseWindowCB : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadUByte();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::CloseWindowCB;
    }

    unsigned char WindowId;
};

struct PacketOpenWindow : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadUByte();
        WindowType = stream->ReadString();
        WindowTitle = stream->ReadChat();
        NumberOfSlots = stream->ReadUByte();

        if (WindowType == "EntityHorse")
            EntityId = stream->ReadInt();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::OpenWindow;
    }

    unsigned char WindowId;
    std::string WindowType;
    std::string WindowTitle;
    unsigned char NumberOfSlots;
    int EntityId;
};

struct PacketWindowItems : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadUByte();
        short count = stream->ReadShort();
        for (int i = 0; i < count; i++)
            SlotData.push_back(stream->ReadSlot());
    }

    int GetPacketId() override {
        return PacketNamePlayCB::WindowItems;
    }

    unsigned char WindowId;
    std::vector<SlotData> SlotData;
};

struct PacketWindowProperty : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadUByte();
        Property = stream->ReadShort();
        Value = stream->ReadShort();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::WindowProperty;
    }

    unsigned char WindowId;
    short Property;
    short Value;
};

struct PacketSetSlot : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadByte();
        Slot = stream->ReadShort();
        SlotData = stream->ReadSlot();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::SetSlot;
    }

    signed char WindowId;
    short Slot;
    SlotData SlotData;
};

struct PacketConfirmTransactionCB : Packet {
    void ToStream(StreamOutput *stream) override {

    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadByte();
        ActionNumber = stream->ReadShort();
        Accepted = stream->ReadBool();
    }

    int GetPacketId() override {
        return PacketNamePlayCB::ConfirmTransactionCB;
    }

    signed char WindowId;
    short ActionNumber;
    bool Accepted;
};

struct PacketConfirmTransactionSB : Packet {
    void ToStream(StreamOutput *stream) override {
        stream->WriteByte(WindowId);
        stream->WriteShort(ActionNumber);
        stream->WriteBool(Accepted);
    }

    void FromStream(StreamInput *stream) override {
        WindowId = stream->ReadByte();
        ActionNumber = stream->ReadShort();
        Accepted = stream->ReadBool();
    }

    int GetPacketId() override {
        return PacketNamePlaySB::ConfirmTransactionSB;
    }

    signed char WindowId;
    short ActionNumber;
    bool Accepted;
};

struct PacketClickWindow : Packet {
    void ToStream(StreamOutput *stream) override {
        stream->WriteUByte(WindowId);
        stream->WriteShort(Slot);
        stream->WriteByte(Button);
        stream->WriteShort(ActionNumber);
        stream->WriteInt(Mode);
        stream->WriteSlot(ClickedItem);
    }

    void FromStream(StreamInput *stream) override {
        
    }

    int GetPacketId() override {
        return PacketNamePlaySB::ClickWindow;
    }

    unsigned char WindowId;
    short Slot;
    signed char Button;
    short ActionNumber;
    int Mode;
    SlotData ClickedItem;

    PacketClickWindow(unsigned char windowId, short slot, signed char button, short actionNumber, int mode, SlotData ClickedItem) : WindowId(windowId), Slot(slot),
        Button(button), ActionNumber(actionNumber), Mode(mode), ClickedItem(ClickedItem) {};
};

struct PacketCloseWindowSB : Packet {
    void ToStream(StreamOutput *stream) override {
        stream->WriteUByte(WindowId);
    }

    void FromStream(StreamInput *stream) override {

    }

    int GetPacketId() override {
        return PacketNamePlaySB::CloseWindowSB;
    }

    unsigned char WindowId;
};