#include "Packet.h"
#include "Utils/FileUtils.h"

#include "ContainerID.h"

auto Packet::getHandler() -> PacketHandlerDispatcherInstance* {
	return *reinterpret_cast<PacketHandlerDispatcherInstance**>((uintptr_t)this + 0x20);
}

auto Packet::getID() -> PacketID {
	return (reinterpret_cast<PacketID(__thiscall*)(void*)>((*reinterpret_cast<void***>(this))[1]))(this);
}

auto Packet::CreatePacket(PacketID id) -> std::shared_ptr<Packet> {
	static void* sig;
	if (!sig) {
		if (Utils::File::getVersion() == _("1.21.80"))
			sig = Utils::Memory::FindPattern(_("48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 50 48 8B 05 5A 84"));
		else if (Utils::File::getVersion() == _("1.21.73"))
			sig = Utils::Memory::FindPattern(_("48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 50 48 8B 05 DA A9"));
		else if (Utils::File::getVersion() == _("1.21.72"))
			sig = Utils::Memory::FindPattern(_("48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 50 48 8B 05 CA A7"));
		else if (Utils::File::getVersion() == _("1.21.71"))
			sig = Utils::Memory::FindPattern(_("48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 50 48 8B 05 2A 34"));
		else if (Utils::File::getVersion() == _("1.21.70"))
			sig = Utils::Memory::FindPattern(_("48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 50 48 8B 05 3A 55"));
		else
			sig = Utils::Memory::FindPattern(_("48 89 5C 24 10 48 89 74 24 18 57 48 83 EC 50 48 8B 05 7A F7"));
	}

	static auto func = reinterpret_cast<std::shared_ptr<Packet>(__fastcall*)(PacketID)>(sig);
	return func(id);
}

auto TextPacket::getType() -> Type {
	return *reinterpret_cast<Type*>((uintptr_t)this + 0x2C);
}

auto TextPacket::setType(Type type) -> void {
	*reinterpret_cast<Type*>((uintptr_t)this + 0x2C) = type;
}

auto TextPacket::getName() -> std::string {
	return reinterpret_cast<std::string32*>((uintptr_t)this + 0x38)->c_str();
}

auto TextPacket::setName(std::string msg) -> void {
	*reinterpret_cast<std::string32*>((uintptr_t)this + 0x38) = msg;
}

auto TextPacket::getMessage() -> std::string {
	return reinterpret_cast<std::string32*>((uintptr_t)this + 0x58)->c_str();
}

auto TextPacket::setMessage(std::string msg) -> void {
	*reinterpret_cast<std::string32*>((uintptr_t)this + 0x58) = msg;
}

auto RemoveActorPacket::getRuntimeID() -> ActorRuntimeID {
	return *reinterpret_cast<ActorRuntimeID*>((uintptr_t)this + 0x30);
}

auto MobEffectPacket::getRuntimeID() -> ActorRuntimeID {
	return *reinterpret_cast<ActorRuntimeID*>((uintptr_t)this + 0x30);
}

auto MobEffectPacket::getEffectID() -> int {
	return *reinterpret_cast<int*>((uintptr_t)this + 0x40);
}

auto InteractPacket::getAction() -> Action {
	return *reinterpret_cast<Action*>((uintptr_t)this + 0x30);
}

auto SetActorMotionPacket::getRuntimeID() -> ActorRuntimeID {
	return *reinterpret_cast<ActorRuntimeID*>((uintptr_t)this + 0x30);
}

auto SetActorMotionPacket::getMotion() -> glm::vec3 {
	return *reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x38);
}

auto SetActorMotionPacket::setMotion(glm::vec3 motion) -> void {
	*reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x38) = motion;
}

auto ContainerOpenPacket::getContainerID() -> ContainerID {
	return *reinterpret_cast<ContainerID*>((uintptr_t)this + 0x2D);
}

auto ContainerOpenPacket::setContainerID(ContainerID containerId) -> void {
	*reinterpret_cast<ContainerID*>((uintptr_t)this + 0x2D) = containerId;
}

auto ContainerOpenPacket::getType() -> SharedTypes::Legacy::ContainerType {
	return *reinterpret_cast<SharedTypes::Legacy::ContainerType*>((uintptr_t)this + 0x2E);
}

auto ContainerOpenPacket::setType(SharedTypes::Legacy::ContainerType type) -> void {
	*reinterpret_cast<SharedTypes::Legacy::ContainerType*>((uintptr_t)this + 0x2E) = type;
}

auto ContainerOpenPacket::setPos(glm::vec3 pos) -> void {
	*reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x3A) = pos;
}

auto ContainerOpenPacket::setEntityUniqueID(ActorUniqueID entityuniqueid) -> void {
	*reinterpret_cast<ActorUniqueID*>((uintptr_t)this + 0x42) = entityuniqueid;
}

auto ContainerClosePacket::getContainerID() -> ContainerID {
	return *reinterpret_cast<ContainerID*>((uintptr_t)this + 0x2D);
}

auto ContainerClosePacket::setContainerID(ContainerID containerId) -> void {
	*reinterpret_cast<ContainerID*>((uintptr_t)this + 0x2D) = containerId;
}

auto ContainerClosePacket::setServerInitiatedClose(bool serverInitiatedClose) -> void {
	*reinterpret_cast<bool*>((uintptr_t)this + 0x2F) = serverInitiatedClose;
}

auto PlayerAuthInputPacket::getPitch() -> float {
	return *reinterpret_cast<float*>((uintptr_t)this + 0x30);
}

auto PlayerAuthInputPacket::getYaw() -> float {
	return *reinterpret_cast<float*>((uintptr_t)this + 0x34);
}

auto PlayerAuthInputPacket::getPos() -> glm::vec3 {
	return *reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x38);
}

auto PlayerAuthInputPacket::getHeadYaw() -> float {
	return *reinterpret_cast<float*>((uintptr_t)this + 0x34 + (sizeof(float) * 4));
}

auto PlayerAuthInputPacket::setPitch(float pitch) -> void {
	*reinterpret_cast<float*>((uintptr_t)this + 0x30) = pitch;
}

auto PlayerAuthInputPacket::setYaw(float yaw) -> void {
	*reinterpret_cast<float*>((uintptr_t)this + 0x34) = yaw;
}

auto PlayerAuthInputPacket::setPos(glm::vec3 pos) -> void {
	*reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x38) = pos;
}

auto PlayerAuthInputPacket::setHeadYaw(float headyaw) -> void {
	*reinterpret_cast<float*>((uintptr_t)this + 0x34 + (sizeof(float) * 4)) = headyaw;
}

auto PlayerAuthInputPacket::setInputData(InputData flag, bool state) -> void {
	reinterpret_cast<std::bitset<65>*>((uintptr_t)this + 0x94)->set(static_cast<size_t>(flag), state);
}

auto PlayerAuthInputPacket::getDeltaPos() -> glm::vec3 {
	return *reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x50);
}

auto PlayerAuthInputPacket::setDeltaPos(glm::vec3 deltaPos) -> void {
	*reinterpret_cast<glm::vec3*>((uintptr_t)this + 0x50) = deltaPos;
}

auto PlayerAuthInputPacket::setVehicleRot(glm::vec2 move) -> void {
	*reinterpret_cast<glm::vec2*>((uintptr_t)this + 0x54) = move;
}

auto PlayerAuthInputPacket::getMove() -> glm::vec2 {
	return *reinterpret_cast<glm::vec2*>((uintptr_t)this + 0x64);
}

auto PlayerAuthInputPacket::setMove(glm::vec2 move) -> void {
	*reinterpret_cast<glm::vec2*>((uintptr_t)this + 0x64) = move;
}

auto PlayerAuthInputPacket::hasInputData(InputData flag) -> bool {
	return reinterpret_cast<std::bitset<65>*>((uintptr_t)this + 0x94)->test(static_cast<size_t>(flag));
}
