player connect-disconnect
This commit is contained in:
1 parent
3f68a8ba07
commit
2e6b93f3ac
16 files changed
+305
-62
No files matched your search
@@ -4,6 +4,7 @@
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace FRG {
|
||||
@@ -143,7 +144,18 @@ std::uint64_t LockstepTimeline::schedule(
|
||||
{
|
||||
const std::uint64_t sequence = nextCommandSequence_++;
|
||||
pending_[currentTick_ + inputDelayTicks_].push_back(
|
||||
{sequence, playerId, target});
|
||||
ScheduledDestinationCommand{sequence, playerId, target});
|
||||
return sequence;
|
||||
}
|
||||
|
||||
std::uint64_t LockstepTimeline::scheduleCharacterEnabled(
|
||||
const std::string& locationId, const std::string& characterId,
|
||||
bool enabled)
|
||||
{
|
||||
const std::uint64_t sequence = nextCommandSequence_++;
|
||||
pending_[currentTick_ + 1].push_back(
|
||||
ScheduledCharacterEnabledCommand{
|
||||
sequence, locationId, characterId, enabled});
|
||||
return sequence;
|
||||
}
|
||||
|
||||
@@ -182,12 +194,26 @@ bool parseDestinationInputMessage(
|
||||
std::string makeTickMessage(const TickMessage& message)
|
||||
{
|
||||
nlohmann::json commands = nlohmann::json::array();
|
||||
for (const ScheduledDestinationCommand& command : message.commands) {
|
||||
commands.push_back({
|
||||
{"commandSequence", command.commandSequence},
|
||||
{"playerId", command.playerId},
|
||||
{"target", targetJson(command.target)}
|
||||
});
|
||||
for (const ScheduledCommand& scheduled : message.commands) {
|
||||
std::visit([&commands](const auto& command) {
|
||||
using T = std::decay_t<decltype(command)>;
|
||||
if constexpr (std::is_same_v<T, ScheduledDestinationCommand>) {
|
||||
commands.push_back({
|
||||
{"type", "destination"},
|
||||
{"commandSequence", command.commandSequence},
|
||||
{"playerId", command.playerId},
|
||||
{"target", targetJson(command.target)}
|
||||
});
|
||||
} else {
|
||||
commands.push_back({
|
||||
{"type", "character_enabled"},
|
||||
{"commandSequence", command.commandSequence},
|
||||
{"locationId", command.locationId},
|
||||
{"characterId", command.characterId},
|
||||
{"enabled", command.enabled}
|
||||
});
|
||||
}
|
||||
}, scheduled);
|
||||
}
|
||||
return envelope("tick", {
|
||||
{"tickId", message.tickId},
|
||||
@@ -209,22 +235,57 @@ bool parseTickMessage(
|
||||
message.commands.clear();
|
||||
std::uint64_t previousSequence = 0;
|
||||
for (const nlohmann::json& value : payload["commands"]) {
|
||||
ScheduledDestinationCommand command;
|
||||
if (!value.is_object() ||
|
||||
!readTick(value, "commandSequence", command.commandSequence, error) ||
|
||||
!value.contains("playerId") || !value["playerId"].is_string() ||
|
||||
!value.contains("target") ||
|
||||
!readTarget(value["target"], command.target, error)) {
|
||||
!readTick(value, "commandSequence", previousSequence, error)) {
|
||||
if (error.empty()) error = "invalid scheduled command";
|
||||
return false;
|
||||
}
|
||||
command.playerId = value["playerId"].get<std::string>();
|
||||
if (command.playerId.empty() || command.commandSequence == 0 ||
|
||||
command.commandSequence <= previousSequence) {
|
||||
const std::string type = value.value("type", "destination");
|
||||
ScheduledCommand command;
|
||||
if (type == "destination") {
|
||||
ScheduledDestinationCommand destination;
|
||||
destination.commandSequence = previousSequence;
|
||||
if (!value.contains("playerId") || !value["playerId"].is_string() ||
|
||||
!value.contains("target") ||
|
||||
!readTarget(value["target"], destination.target, error)) {
|
||||
if (error.empty()) error = "invalid destination command";
|
||||
return false;
|
||||
}
|
||||
destination.playerId = value["playerId"].get<std::string>();
|
||||
if (destination.playerId.empty()) {
|
||||
error = "destination command playerId must not be empty";
|
||||
return false;
|
||||
}
|
||||
command = std::move(destination);
|
||||
} else if (type == "character_enabled") {
|
||||
ScheduledCharacterEnabledCommand enabled;
|
||||
enabled.commandSequence = previousSequence;
|
||||
if (!value.contains("locationId") || !value["locationId"].is_string() ||
|
||||
!value.contains("characterId") || !value["characterId"].is_string() ||
|
||||
!value.contains("enabled") || !value["enabled"].is_boolean()) {
|
||||
error = "invalid character enabled command";
|
||||
return false;
|
||||
}
|
||||
enabled.locationId = value["locationId"].get<std::string>();
|
||||
enabled.characterId = value["characterId"].get<std::string>();
|
||||
enabled.enabled = value["enabled"].get<bool>();
|
||||
if (enabled.locationId.empty() || enabled.characterId.empty()) {
|
||||
error = "character enabled command IDs must not be empty";
|
||||
return false;
|
||||
}
|
||||
command = std::move(enabled);
|
||||
} else {
|
||||
error = "unsupported scheduled command type";
|
||||
return false;
|
||||
}
|
||||
if (previousSequence == 0 ||
|
||||
(!message.commands.empty() &&
|
||||
previousSequence <= std::visit(
|
||||
[](const auto& item) { return item.commandSequence; },
|
||||
message.commands.back()))) {
|
||||
error = "commands must have unique increasing sequences";
|
||||
return false;
|
||||
}
|
||||
previousSequence = command.commandSequence;
|
||||
message.commands.push_back(std::move(command));
|
||||
}
|
||||
message.stateHash = payload.value("stateHash", std::string());
|
||||
|
||||
Reference in new issue
Block a user