mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-12 23:40:53 +01:00
513 lines
14 KiB
C++
513 lines
14 KiB
C++
#include <TiltedCore/Stl.hpp>
|
|
#include <TiltedCore/Allocator.hpp>
|
|
#include <TiltedCore/Buffer.hpp>
|
|
#include <TiltedCore/Serialization.hpp>
|
|
|
|
#include <optional>
|
|
|
|
#include <glm/vec2.hpp>
|
|
#include <glm/vec3.hpp>
|
|
|
|
#include "StringCache.h"
|
|
#include "Messages/StringCacheUpdate.h"
|
|
|
|
#include <catch2/catch.hpp>
|
|
|
|
#include <Messages/ClientMessageFactory.h>
|
|
#include <Messages/ServerMessageFactory.h>
|
|
#include <Structs/Vector2_NetQuantize.h>
|
|
|
|
#include <TiltedCore/Math.hpp>
|
|
#include <TiltedCore/Platform.hpp>
|
|
|
|
using namespace TiltedPhoques;
|
|
|
|
TEST_CASE("Encoding factory", "[encoding.factory]")
|
|
{
|
|
Buffer buff(1000);
|
|
|
|
{
|
|
AuthenticationRequest request;
|
|
request.Token = "TesSt";
|
|
|
|
Buffer::Writer writer(&buff);
|
|
request.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
const ClientMessageFactory factory;
|
|
auto pMessage = factory.Extract(reader);
|
|
|
|
REQUIRE(pMessage);
|
|
REQUIRE(pMessage->GetOpcode() == request.GetOpcode());
|
|
|
|
auto pRequest = CastUnique<AuthenticationRequest>(std::move(pMessage));
|
|
REQUIRE(pRequest->Token == request.Token);
|
|
}
|
|
|
|
{
|
|
PartyAcceptInviteRequest request;
|
|
request.InviterId = 123456;
|
|
|
|
Buffer::Writer writer(&buff);
|
|
request.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
const ClientMessageFactory factory;
|
|
auto pMessage = factory.Extract(reader);
|
|
|
|
REQUIRE(pMessage);
|
|
REQUIRE(pMessage->GetOpcode() == request.GetOpcode());
|
|
|
|
auto pRequest = CastUnique<PartyAcceptInviteRequest>(std::move(pMessage));
|
|
REQUIRE(pRequest->InviterId == request.InviterId);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Static structures", "[encoding.static]")
|
|
{
|
|
GIVEN("GameId")
|
|
{
|
|
GameId sendObjects, recvObjects;
|
|
sendObjects.ModId = 1456987;
|
|
sendObjects.BaseId = 0x789654;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendObjects.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvObjects.Deserialize(reader);
|
|
|
|
REQUIRE(sendObjects == recvObjects);
|
|
}
|
|
}
|
|
|
|
GIVEN("Vector3_NetQuantize")
|
|
{
|
|
Vector3_NetQuantize sendObjects, recvObjects;
|
|
sendObjects.x = 142.56f;
|
|
sendObjects.y = 45687.7f;
|
|
sendObjects.z = -142.56f;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendObjects.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvObjects.Deserialize(reader);
|
|
|
|
REQUIRE(sendObjects == recvObjects);
|
|
}
|
|
}
|
|
|
|
GIVEN("Vector2_NetQuantize")
|
|
{
|
|
Vector2_NetQuantize sendObjects, recvObjects;
|
|
sendObjects.x = 1000.89f;
|
|
sendObjects.y = -485632.75f;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendObjects.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvObjects.Deserialize(reader);
|
|
|
|
REQUIRE(sendObjects == recvObjects);
|
|
}
|
|
}
|
|
|
|
GIVEN("Rotator2_NetQuantize")
|
|
{
|
|
Rotator2_NetQuantize sendObjects, recvObjects;
|
|
sendObjects.x = 1.89f;
|
|
sendObjects.y = TiltedPhoques::Pi * 2.0f;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendObjects.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvObjects.Deserialize(reader);
|
|
|
|
REQUIRE(sendObjects == recvObjects);
|
|
}
|
|
}
|
|
|
|
GIVEN("Rotator2_NetQuantize needing wrap")
|
|
{
|
|
// This test is a bit dangerous as floating errors can lead to sendObjects != recvObjects but the difference is minuscule so we don't care abut such cases
|
|
Rotator2_NetQuantize sendObjects, recvObjects;
|
|
sendObjects.x = -1.87f;
|
|
sendObjects.y = static_cast<float>(TiltedPhoques::Pi) * 18.0f + 3.6f;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendObjects.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvObjects.Deserialize(reader);
|
|
|
|
REQUIRE(sendObjects == recvObjects);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Differential structures", "[encoding.differential]")
|
|
{
|
|
GIVEN("Full ActionEvent")
|
|
{
|
|
ActionEvent sendAction, recvAction;
|
|
|
|
sendAction.ActionId = 42;
|
|
sendAction.State1 = 6547;
|
|
sendAction.Tick = 48;
|
|
sendAction.ActorId = 12345678;
|
|
sendAction.EventName = "test";
|
|
sendAction.IdleId = 87964;
|
|
sendAction.State2 = 8963;
|
|
sendAction.TargetEventName = "toast";
|
|
sendAction.TargetId = 963741;
|
|
sendAction.Type = 4;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendAction.GenerateDifferential(recvAction, writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvAction.ApplyDifferential(reader);
|
|
|
|
REQUIRE(sendAction == recvAction);
|
|
}
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendAction.EventName = "Plot twist !";
|
|
|
|
sendAction.GenerateDifferential(recvAction, writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvAction.ApplyDifferential(reader);
|
|
|
|
REQUIRE(sendAction == recvAction);
|
|
}
|
|
}
|
|
|
|
GIVEN("A single cached event name")
|
|
{
|
|
ActionEvent sendAction, recvAction;
|
|
|
|
TP_UNUSED(StringCache::Get().Add("test"))
|
|
|
|
sendAction.ActionId = 42;
|
|
sendAction.State1 = 6547;
|
|
sendAction.Tick = 48;
|
|
sendAction.ActorId = 12345678;
|
|
sendAction.EventName = "test";
|
|
sendAction.IdleId = 87964;
|
|
sendAction.State2 = 8963;
|
|
sendAction.TargetEventName = "toast";
|
|
sendAction.TargetId = 963741;
|
|
sendAction.Type = 4;
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendAction.GenerateDifferential(recvAction, writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvAction.ApplyDifferential(reader);
|
|
|
|
REQUIRE(sendAction == recvAction);
|
|
}
|
|
|
|
{
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendAction.EventName = "Plot twist !";
|
|
|
|
sendAction.GenerateDifferential(recvAction, writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvAction.ApplyDifferential(reader);
|
|
|
|
REQUIRE(sendAction == recvAction);
|
|
}
|
|
}
|
|
|
|
GIVEN("Full Mods")
|
|
{
|
|
Mods sendMods, recvMods;
|
|
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
|
|
sendMods.ModList.push_back({"Hello", 42});
|
|
sendMods.ModList.push_back({"Hi", 14});
|
|
sendMods.ModList.push_back({"Test", 8});
|
|
sendMods.ModList.push_back({"Toast", 49});
|
|
|
|
sendMods.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvMods.Deserialize(reader);
|
|
|
|
REQUIRE(sendMods == recvMods);
|
|
}
|
|
|
|
GIVEN("AnimationVariables")
|
|
{
|
|
AnimationVariables vars, recvVars;
|
|
|
|
vars.Booleans.resize(76);
|
|
String testString("\xDE\xAD\xBE\xEF"
|
|
"\xDE\xAD\xBE\xEF\x76\xB");
|
|
vars.String_to_VectorBool(testString, vars.Booleans);
|
|
|
|
vars.Floats.push_back(1.f);
|
|
vars.Floats.push_back(7.f);
|
|
vars.Floats.push_back(12.f);
|
|
vars.Floats.push_back(0.f);
|
|
vars.Floats.push_back(145.f);
|
|
vars.Floats.push_back(100.f);
|
|
vars.Floats.push_back(-1.f);
|
|
|
|
vars.Integers.push_back(0);
|
|
vars.Integers.push_back(12000);
|
|
vars.Integers.push_back(06);
|
|
vars.Integers.push_back(7778);
|
|
vars.Integers.push_back(41104539);
|
|
|
|
Buffer buff(1000);
|
|
{
|
|
Buffer::Writer writer(&buff);
|
|
|
|
vars.GenerateDiff(recvVars, writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvVars.ApplyDiff(reader);
|
|
|
|
REQUIRE(vars.Booleans == recvVars.Booleans);
|
|
REQUIRE(vars.Floats == recvVars.Floats);
|
|
REQUIRE(vars.Integers == recvVars.Integers);
|
|
}
|
|
|
|
vars.Booleans.resize(33);
|
|
vars.Booleans[16] = false;
|
|
vars.Booleans[17] = false;
|
|
vars.Booleans[18] = false;
|
|
vars.Booleans[19] = false;
|
|
vars.Floats[3] = 42.f;
|
|
vars.Integers[0] = 18;
|
|
vars.Integers[3] = 0;
|
|
|
|
{
|
|
Buffer::Writer writer(&buff);
|
|
|
|
vars.GenerateDiff(recvVars, writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
recvVars.ApplyDiff(reader);
|
|
|
|
REQUIRE(vars.Booleans == recvVars.Booleans);
|
|
REQUIRE(vars.Floats == recvVars.Floats);
|
|
REQUIRE(vars.Integers == recvVars.Integers);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Packets", "[encoding.packets]")
|
|
{
|
|
SECTION("AuthenticationRequest")
|
|
{
|
|
Buffer buff(1000);
|
|
|
|
AuthenticationRequest sendMessage, recvMessage;
|
|
sendMessage.Token = "TesSt";
|
|
sendMessage.UserMods.ModList.push_back({"Hello", 42});
|
|
sendMessage.UserMods.ModList.push_back({"Hi", 14});
|
|
sendMessage.UserMods.ModList.push_back({"Test", 8});
|
|
sendMessage.UserMods.ModList.push_back({"Toast", 49});
|
|
|
|
Buffer::Writer writer(&buff);
|
|
sendMessage.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
uint64_t trash;
|
|
reader.ReadBits(trash, 8); // pop opcode
|
|
|
|
recvMessage.DeserializeRaw(reader);
|
|
|
|
REQUIRE(sendMessage == recvMessage);
|
|
}
|
|
|
|
SECTION("AuthenticationResponse")
|
|
{
|
|
Buffer buff(1000);
|
|
|
|
AuthenticationResponse sendMessage, recvMessage;
|
|
sendMessage.Type = AuthenticationResponse::ResponseType::kAccepted;
|
|
sendMessage.UserMods.ModList.push_back({"Hello", 42});
|
|
sendMessage.UserMods.ModList.push_back({"Hi", 14});
|
|
sendMessage.UserMods.ModList.push_back({"Test", 8});
|
|
sendMessage.UserMods.ModList.push_back({"Toast", 49});
|
|
|
|
Buffer::Writer writer(&buff);
|
|
sendMessage.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
uint64_t trash;
|
|
reader.ReadBits(trash, 8); // pop opcode
|
|
|
|
recvMessage.DeserializeRaw(reader);
|
|
|
|
REQUIRE(sendMessage == recvMessage);
|
|
}
|
|
|
|
SECTION("CancelAssignmentRequest")
|
|
{
|
|
Buffer buff(1000);
|
|
|
|
CancelAssignmentRequest sendMessage, recvMessage;
|
|
sendMessage.Cookie = 14523698;
|
|
Buffer::Writer writer(&buff);
|
|
sendMessage.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
uint64_t trash;
|
|
reader.ReadBits(trash, 8); // pop opcode
|
|
|
|
recvMessage.DeserializeRaw(reader);
|
|
|
|
REQUIRE(sendMessage == recvMessage);
|
|
}
|
|
|
|
SECTION("AssignCharacterRequest")
|
|
{
|
|
Buffer buff(1000);
|
|
|
|
ActionEvent sendAction;
|
|
sendAction.ActionId = 42;
|
|
sendAction.State1 = 6547;
|
|
sendAction.Tick = 48;
|
|
sendAction.ActorId = 12345678;
|
|
sendAction.EventName = "test";
|
|
sendAction.IdleId = 87964;
|
|
sendAction.State2 = 8963;
|
|
sendAction.TargetEventName = "toast";
|
|
sendAction.TargetId = 963741;
|
|
sendAction.Type = 4;
|
|
|
|
AssignCharacterRequest sendMessage, recvMessage;
|
|
sendMessage.Cookie = 14523698;
|
|
sendMessage.AppearanceBuffer = "toto";
|
|
sendMessage.CellId.BaseId = 45;
|
|
sendMessage.FormId.ModId = 48;
|
|
sendMessage.ReferenceId.BaseId = 456799;
|
|
sendMessage.ReferenceId.ModId = 4079;
|
|
sendMessage.LatestAction = sendAction;
|
|
sendMessage.Position.x = -452.4f;
|
|
sendMessage.Position.y = 452.4f;
|
|
sendMessage.Position.z = 125452.4f;
|
|
sendMessage.Rotation.x = -1.87f;
|
|
sendMessage.Rotation.y = 45.35f;
|
|
|
|
Buffer::Writer writer(&buff);
|
|
sendMessage.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
uint64_t trash;
|
|
reader.ReadBits(trash, 8); // pop opcode
|
|
|
|
recvMessage.DeserializeRaw(reader);
|
|
|
|
REQUIRE(sendMessage == recvMessage);
|
|
}
|
|
|
|
GIVEN("ClientReferencesMoveRequest")
|
|
{
|
|
ClientReferencesMoveRequest sendMessage, recvMessage;
|
|
auto& update = sendMessage.Updates[1];
|
|
auto& move = update.UpdatedMovement;
|
|
|
|
AnimationVariables vars;
|
|
vars.Booleans.resize(76);
|
|
String testString("\xDE\xAD\xBE\xEF\x76\xB");
|
|
vars.String_to_VectorBool(testString, vars.Booleans);
|
|
|
|
vars.Floats.push_back(1.f);
|
|
vars.Floats.push_back(7.f);
|
|
vars.Floats.push_back(12.f);
|
|
vars.Floats.push_back(0.f);
|
|
vars.Floats.push_back(145.f);
|
|
vars.Floats.push_back(100.f);
|
|
vars.Floats.push_back(-1.f);
|
|
|
|
vars.Integers.push_back(0);
|
|
vars.Integers.push_back(12000);
|
|
vars.Integers.push_back(06);
|
|
vars.Integers.push_back(7778);
|
|
vars.Integers.push_back(41104539);
|
|
|
|
move.Variables = vars;
|
|
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
sendMessage.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
uint64_t trash;
|
|
reader.ReadBits(trash, 8); // pop opcode
|
|
|
|
recvMessage.DeserializeRaw(reader);
|
|
|
|
REQUIRE(recvMessage.Updates[1].UpdatedMovement == sendMessage.Updates[1].UpdatedMovement);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("StringCache", "[encoding.string_cache]")
|
|
{
|
|
SECTION("Messages")
|
|
{
|
|
StringCacheUpdate update;
|
|
update.Values.push_back("Hello");
|
|
update.Values.push_back("Bye");
|
|
|
|
Buffer buff(1000);
|
|
Buffer::Writer writer(&buff);
|
|
update.Serialize(writer);
|
|
|
|
Buffer::Reader reader(&buff);
|
|
|
|
uint64_t trash;
|
|
reader.ReadBits(trash, 8); // pop opcode
|
|
|
|
StringCacheUpdate recvUpdate;
|
|
recvUpdate.DeserializeRaw(reader);
|
|
|
|
REQUIRE(update == recvUpdate);
|
|
}
|
|
}
|