Skip to content

Commit 3a57f27

Browse files
committed
Add multiplayer abstractions
Add multi-platform socket abstractions Add Udp and Tcp client/server socket handlers Add RingBuffer Add PacketReaderAdapter Add PacketBuilder Add byte Marshal encode and decode Deduplicate stack_string behaviors into StackString Add `GameManager::get_elapsed_microseconds` Add `GameManager::get_elapsed_milliseconds` Add RingBuffer tests Add IpAddress tests Add UdpServer tests Add ReliableUdpServer tess Add TcpServer tests Add Marshal tests Add mas-bandwidth/reliable@57b0c90
1 parent bee92b5 commit 3a57f27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+8000
-183
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@
3030
path = deps/memory
3131
url = https://github.com/foonathan/memory
3232
ignore = dirty
33+
[submodule "deps/reliable"]
34+
path = deps/reliable
35+
url = https://github.com/mas-bandwidth/reliable

deps/SCsub

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,36 @@ def build_memory(env):
111111

112112
env.exposed_includes += env.memory["INCPATH"]
113113

114+
def build_reliable(env):
115+
import os
116+
117+
if env["dev_build"]:
118+
env.Append(CPPDEFINES=["RELIABLE_DEBUG"])
119+
else:
120+
env.Append(CPPDEFINES=["RELIABLE_RELEASE"])
121+
reliable_env = env.Clone()
122+
123+
include_path = "reliable"
124+
include_dir = reliable_env.Dir(include_path)
125+
sources = [os.path.join(include_path, "reliable.c")]
126+
env.reliable_sources = sources
127+
library_name = "libreliable" + env["LIBSUFFIX"]
128+
library = reliable_env.StaticLibrary(target=os.path.join(include_path, library_name), source=sources)
129+
Default(library)
130+
131+
env.reliable = {}
132+
env.reliable["INCPATH"] = [include_dir]
133+
134+
env.Append(CPPPATH=env.reliable["INCPATH"])
135+
if env.get("is_msvc", False):
136+
env.Append(CXXFLAGS=["/external:I", include_dir, "/external:W0"])
137+
else:
138+
env.Append(CXXFLAGS=["-isystem", include_dir])
139+
env.Append(LIBPATH=include_dir)
140+
env.Prepend(LIBS=[library_name])
141+
142+
env.exposed_includes += env.reliable["INCPATH"]
143+
114144
def link_tbb(env):
115145
import sys
116146
if not env.get("is_msvc", False) and not env.get("use_mingw", False) and sys.platform != "darwin":
@@ -123,4 +153,5 @@ build_colony(env)
123153
build_function2(env)
124154
build_std_function(env)
125155
build_memory(env)
156+
build_reliable(env)
126157
link_tbb(env)

deps/reliable

Submodule reliable added at 57b0c90

src/headless/main.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,12 @@ static bool run_headless(fs::path const& root, memory::vector<memory::string>& m
127127
Dataloader::path_vector_t roots = { root };
128128
Dataloader::path_vector_t replace_paths = {};
129129

130-
GameManager game_manager { []() {
131-
Logger::info("State updated");
132-
} };
130+
GameManager game_manager {
131+
[] {
132+
Logger::info("State updated");
133+
},
134+
nullptr, nullptr
135+
};
133136

134137
Logger::info("Commit hash: ", GameManager::get_commit_hash());
135138

src/openvic-simulation/GameManager.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,39 @@
11
#include "GameManager.hpp"
22

3+
#include <chrono>
4+
35
using namespace OpenVic;
46

7+
static std::chrono::time_point elapsed_time_begin = std::chrono::high_resolution_clock::now();
8+
9+
GameManager::elapsed_time_getter_func_t GameManager::get_elapsed_usec_time_callback = []() -> uint64_t {
10+
std::chrono::time_point current = std::chrono::high_resolution_clock::now();
11+
return std::chrono::duration_cast<std::chrono::microseconds>(current - elapsed_time_begin).count();
12+
};
13+
14+
GameManager::elapsed_time_getter_func_t GameManager::get_elapsed_msec_time_callback = []() -> uint64_t {
15+
std::chrono::time_point current = std::chrono::high_resolution_clock::now();
16+
return std::chrono::duration_cast<std::chrono::milliseconds>(current - elapsed_time_begin).count();
17+
};
18+
519
GameManager::GameManager(
6-
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback
20+
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback,
21+
elapsed_time_getter_func_t new_get_elapsed_usec_callback,
22+
elapsed_time_getter_func_t new_get_elapsed_msec_callback
723
) : gamestate_updated_callback {
824
new_gamestate_updated_callback ? std::move(new_gamestate_updated_callback) : []() {}
9-
}, definitions_loaded { false }, mod_descriptors_loaded { false } {}
25+
}, definitions_loaded { false }, mod_descriptors_loaded { false } {
26+
if (new_get_elapsed_usec_callback) {
27+
get_elapsed_usec_time_callback = { std::move(new_get_elapsed_usec_callback) };
28+
}
29+
if (new_get_elapsed_msec_callback) {
30+
get_elapsed_msec_time_callback = { std::move(new_get_elapsed_msec_callback) };
31+
}
32+
33+
if (bool(new_get_elapsed_usec_callback) != bool(new_get_elapsed_msec_callback)) {
34+
Logger::warning("Only one of the elapsed time callbacks was set.");
35+
}
36+
}
1037

1138
bool GameManager::load_mod_descriptors(std::span<const memory::string> descriptors) {
1239
if (mod_descriptors_loaded) {
@@ -97,3 +124,11 @@ bool GameManager::update_clock() {
97124

98125
return instance_manager->update_clock();
99126
}
127+
128+
uint64_t GameManager::get_elapsed_microseconds() {
129+
return get_elapsed_usec_time_callback();
130+
}
131+
132+
uint64_t GameManager::get_elapsed_milliseconds() {
133+
return get_elapsed_msec_time_callback();
134+
}

src/openvic-simulation/GameManager.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@
1010
#include "openvic-simulation/misc/GameRulesManager.hpp"
1111
#include "openvic-simulation/gen/commit_info.gen.hpp"
1212

13+
#include <function2/function2.hpp>
14+
1315
namespace OpenVic {
1416
struct GameManager {
17+
using elapsed_time_getter_func_t = fu2::function_base<true, true, fu2::capacity_none, false, false, uint64_t() const>;
18+
1519
private:
20+
static elapsed_time_getter_func_t get_elapsed_usec_time_callback;
21+
static elapsed_time_getter_func_t get_elapsed_msec_time_callback;
22+
1623
GameRulesManager PROPERTY(game_rules_manager);
1724
Dataloader PROPERTY(dataloader);
1825
DefinitionManager PROPERTY(definition_manager);
@@ -25,7 +32,9 @@ namespace OpenVic {
2532

2633
public:
2734
GameManager(
28-
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback
35+
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback,
36+
elapsed_time_getter_func_t new_get_elapsed_usec_callback,
37+
elapsed_time_getter_func_t new_get_elapsed_msec_callback
2938
);
3039

3140
inline constexpr InstanceManager* get_instance_manager() {
@@ -55,5 +64,8 @@ namespace OpenVic {
5564
static constexpr uint64_t get_commit_timestamp() {
5665
return SIM_COMMIT_TIMESTAMP;
5766
}
67+
68+
static uint64_t get_elapsed_microseconds();
69+
static uint64_t get_elapsed_milliseconds();
5870
};
5971
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
#include "HostnameAddress.hpp"
3+
4+
#include <charconv>
5+
#include <system_error>
6+
7+
#include "openvic-simulation/multiplayer/lowlevel/IpAddress.hpp"
8+
#include "openvic-simulation/multiplayer/lowlevel/NetworkResolver.hpp"
9+
10+
using namespace OpenVic;
11+
12+
HostnameAddress::HostnameAddress() = default;
13+
14+
HostnameAddress::HostnameAddress(IpAddress const& address) : _resolved_address(address) {}
15+
16+
HostnameAddress::HostnameAddress(std::string_view name_or_address) : HostnameAddress() {
17+
std::from_chars_result result =
18+
_resolved_address.from_chars(name_or_address.data(), name_or_address.data() + name_or_address.size());
19+
if (result.ec != std::errc {}) {
20+
_resolved_address = NetworkResolver::singleton().resolve_hostname(name_or_address);
21+
}
22+
}
23+
24+
IpAddress const& HostnameAddress::resolved_address() const {
25+
return _resolved_address;
26+
}
27+
28+
void HostnameAddress::set_resolved_address(IpAddress const& address) {
29+
_resolved_address = address;
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include <string_view>
4+
5+
#include "openvic-simulation/multiplayer/lowlevel/IpAddress.hpp"
6+
7+
namespace OpenVic {
8+
struct HostnameAddress {
9+
HostnameAddress();
10+
HostnameAddress(IpAddress const& address);
11+
HostnameAddress(std::string_view name_or_address);
12+
13+
IpAddress const& resolved_address() const;
14+
void set_resolved_address(IpAddress const& address);
15+
16+
private:
17+
IpAddress _resolved_address;
18+
};
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "IpAddress.hpp"
2+
3+
#include "openvic-simulation/utility/Containers.hpp"
4+
5+
using namespace OpenVic;
6+
7+
memory::string IpAddress::to_string(bool prefer_ipv4, to_chars_option option) const {
8+
stack_string result = to_array(prefer_ipv4, option);
9+
if (OV_unlikely(result.empty())) {
10+
return {};
11+
}
12+
13+
return result;
14+
}
15+
16+
IpAddress::operator memory::string() const {
17+
return to_string();
18+
}

0 commit comments

Comments
 (0)