Skip to content

Commit

Permalink
Basis for player simulation
Browse files Browse the repository at this point in the history
  • Loading branch information
tuokri committed Mar 5, 2024
1 parent a17146b commit 601d42e
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
9 changes: 8 additions & 1 deletion A2SServer/A2SServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ public A2SRequestPackage Decode(ref ReadOnlySequence<byte> buffer, object contex
}
}

public class PlayerInfo
{
public string Name = "";
public int Score = 0;
public double Duration = 0;
}

public class Info
{
public byte Protocol = 0;
Expand Down Expand Up @@ -169,7 +176,7 @@ public static byte[] MakeInfoResponsePacket(ref Info info)
return bytes.ToArray();
}

public static byte[] MakePlayerResponsePacket()
public static byte[] MakePlayerResponsePacket(ref List<PlayerInfo> players)
{
var data = new byte[]
{
Expand Down
49 changes: 48 additions & 1 deletion A2SServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,48 @@
var rules = rulesTable.ToDictionary(
kv => kv.Key, kv => (string)kv.Value);

var playersTable = (TomlTable)cfg["players"];
var playersStrategy = (string)playersTable["strategy"];
var playersGame = (string)playersTable["game"];
var playerNames =
from name in (TomlArray)playersTable["names"] select (string)name;

var rng = new Random();

var simPlayers = new List<PlayerInfo>();
foreach (var name in playerNames)
{
simPlayers.Add(new PlayerInfo
{
Name = name,
Score = rng.Next(-50, 250),
Duration = RandDouble(ref rng, 0, 60),
});
}

const double timerIntervalSecs = 5000;
double roundTime = 0;
var maxRoundTime = RandDouble(ref rng, 1800, 3600);
var playerUpdateTimer = new System.Timers.Timer(timerIntervalSecs);
playerUpdateTimer.Elapsed += (sender, eventArgs) =>
{
roundTime += timerIntervalSecs;

if (roundTime > maxRoundTime)
{
roundTime = 0;
// Reset player scores and play times.
}
};
playerUpdateTimer.AutoReset = true;
playerUpdateTimer.Enabled = true;

// Get random match duration.
// Set game players from pool of names.
// Set random starting times for players in range.
// Increment times every x seconds.
// Adjust player scores semi randomly every x seconds.

Console.WriteLine($"starting A2S server on '{host}:{queryPort}'");

var addr = host is "" or "0.0.0.0"
Expand Down Expand Up @@ -106,7 +148,7 @@
{
Constants.A2SInfoRequestHeader => Utils.MakeInfoResponsePacket(ref info),
Constants.A2SRulesRequestHeader => Utils.MakeRulesResponsePacket(ref rules),
Constants.A2SPlayerRequestHeader => Utils.MakePlayerResponsePacket(),
Constants.A2SPlayerRequestHeader => Utils.MakePlayerResponsePacket(ref simPlayers),
_ => throw new ProtocolException($"invalid header: 0x{p.Header:x}")
};

Expand All @@ -130,3 +172,8 @@
Console.WriteLine("stopping");

return 0;

static double RandDouble(ref Random rng, double min, double max)
{
return rng.NextDouble() * (max - min) + min;
}
11 changes: 11 additions & 0 deletions ds_config_template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,14 @@ password_protected = false
key = "value_pair1"
key2 = "vaue_pair2"
free = "form data here"

[players]
# TODO: player advertising strategies.
# - Increment score and time played to mimic actual gameplay.
strategy = "dynamic" # One of "dynamic", "static".
game = "generic" # "Generic" or "rs2".
names = [
"foo",
"bar",
"baz",
]

0 comments on commit 601d42e

Please sign in to comment.