mirror of
https://github.com/SoDOff-Project/sodoff-mmo.git
synced 2025-10-11 08:18:49 -07:00
More changes to appease the Pull Request.
This commit is contained in:
parent
c26153003f
commit
986193886e
@ -7,7 +7,7 @@ namespace sodoffmmo.CommandHandlers;
|
||||
[ExtensionCommandHandler("SCE")]
|
||||
class CounterEventHandler : CommandHandler {
|
||||
public override Task Handle(Client client, NetworkObject receivedObject) { // {"a":13,"c":1,"p":{"c":"SCE","p":{"NAME":"COUNT"},"r":-1}}
|
||||
if (client.Room is AmbassadorRoom room) {
|
||||
if (client.Room is SpecialRoom room) {
|
||||
string name = receivedObject.Get<NetworkObject>("p").Get<string>("NAME");
|
||||
if (name == "COUNT" || name == "COUNT2" || name == "COUNT3") {
|
||||
int index = name switch {
|
||||
@ -16,9 +16,7 @@ class CounterEventHandler : CommandHandler {
|
||||
"COUNT3" => 2
|
||||
};
|
||||
room.ambassadorGauges[index] = Math.Min(100, room.ambassadorGauges[index]+(1/Configuration.ServerConfiguration.AmbassadorGaugePlayers));
|
||||
NetworkArray vars = new();
|
||||
room.AddRoomData(vars);
|
||||
room.Send(Utils.VlNetworkPacket(vars, client.Room.Id));
|
||||
room.Send(Utils.VlNetworkPacket(room.GetRoomVars(), client.Room.Id));
|
||||
} else {
|
||||
Console.WriteLine($"Invalid attempt to increment room var {name} in {room.Name}.");
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class SetUserVariablesHandler : CommandHandler {
|
||||
client.PlayerData.InitFromNetworkData(suvData);
|
||||
UpdatePlayersInRoom();
|
||||
SendSUVToPlayerInRoom();
|
||||
client.Room.SendAllAlerts(client);
|
||||
if (client.Room is SpecialRoom room) room.SendAllAlerts(client);
|
||||
} else {
|
||||
UpdateVars();
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
using sodoffmmo.Data;
|
||||
|
||||
namespace sodoffmmo.Core;
|
||||
|
||||
public class AmbassadorRoom : Room {
|
||||
public double[] ambassadorGauges;
|
||||
readonly System.Timers.Timer? ambassadorTimer;
|
||||
|
||||
public AmbassadorRoom(string name) : base(name) {
|
||||
Console.WriteLine($"Setup Ambassador for {name}");
|
||||
ambassadorGauges = new double[3]; // There is always a maximum of 3.
|
||||
for (int i=0;i<3;i++) ambassadorGauges[i] = Configuration.ServerConfiguration.AmbassadorGaugeStart;
|
||||
ambassadorTimer = new(Configuration.ServerConfiguration.AmbassadorGaugeDecayRate * 1000) {
|
||||
AutoReset = true,
|
||||
Enabled = true
|
||||
};
|
||||
ambassadorTimer.Elapsed += (sender, e) => {
|
||||
if (!Configuration.ServerConfiguration.AmbassadorGaugeDecayOnlyWhenInRoom || clients.Count > 0) {
|
||||
for (int i=0;i<3;i++) ambassadorGauges[i] = Math.Max(0, ambassadorGauges[i]-1);
|
||||
NetworkArray vars = new();
|
||||
AddRoomData(vars);
|
||||
Send(Utils.VlNetworkPacket(vars, Id));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal override void AddRoomData(NetworkArray vars) {
|
||||
base.AddRoomData(vars);
|
||||
vars.Add(NetworkArray.VlElement("COUNT", (int)Math.Round(ambassadorGauges[0]), isPersistent: true));
|
||||
vars.Add(NetworkArray.VlElement("COUNT2", (int)Math.Round(ambassadorGauges[1]), isPersistent: true));
|
||||
vars.Add(NetworkArray.VlElement("COUNT3", (int)Math.Round(ambassadorGauges[2]), isPersistent: true));
|
||||
}
|
||||
}
|
158
src/Core/Room.cs
158
src/Core/Room.cs
@ -7,7 +7,7 @@ public class Room {
|
||||
static object RoomsListLock = new object();
|
||||
protected static Dictionary<string, Room> rooms = new();
|
||||
|
||||
protected List<Client> clients = new();
|
||||
List<Client> clients = new();
|
||||
protected object roomLock = new object();
|
||||
|
||||
public int Id { get; private set; }
|
||||
@ -82,10 +82,8 @@ public class Room {
|
||||
|
||||
public static Room GetOrAdd(string name, bool autoRemove = false) {
|
||||
lock(RoomsListLock) {
|
||||
if (!Room.Exists(name)) {
|
||||
if (Configuration.ServerConfiguration.AmbassadorRooms.Contains(name)) return new AmbassadorRoom(name);
|
||||
if (!Room.Exists(name))
|
||||
return new Room(name, autoRemove: autoRemove);
|
||||
}
|
||||
return rooms[name];
|
||||
}
|
||||
}
|
||||
@ -113,10 +111,7 @@ public class Room {
|
||||
roomInfo.Add(false); // is password protected
|
||||
roomInfo.Add((short)clients.Count); // player count
|
||||
roomInfo.Add((short)4096); // max player count
|
||||
NetworkArray roomVars = new();
|
||||
AddRoomData(roomVars);
|
||||
for (int i=0;i<RoomVariables.Length;i++) roomVars.Add(RoomVariables[i]);
|
||||
roomInfo.Add(roomVars); // variables (plus added data)
|
||||
roomInfo.Add(GetRoomVars()); // variables (plus added data)
|
||||
roomInfo.Add((short)0); // spectator count
|
||||
roomInfo.Add((short)0); // max spectator count
|
||||
|
||||
@ -148,9 +143,7 @@ public class Room {
|
||||
r1.Add(false);
|
||||
r1.Add((short)clients.Count); // player count
|
||||
r1.Add((short)4096); // max player count
|
||||
NetworkArray vars = new();
|
||||
AddRoomData(vars);
|
||||
r1.Add(vars);
|
||||
r1.Add(GetRoomVars());
|
||||
r1.Add((short)0);
|
||||
r1.Add((short)0);
|
||||
|
||||
@ -161,146 +154,5 @@ public class Room {
|
||||
return NetworkObject.WrapObject(0, 15, obj).Serialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add extra data for the client to recieve upon joining the room.
|
||||
/// </summary>
|
||||
/// <param name="vars">Existing room variables.</param>
|
||||
internal virtual void AddRoomData(NetworkArray vars) {}
|
||||
|
||||
private int alertId = -1;
|
||||
private Random random = new Random();
|
||||
|
||||
List<AlertInfo> alerts = new();
|
||||
|
||||
public void AddAlert(AlertInfo alert) {
|
||||
alerts.Add(alert);
|
||||
ResetAlertTimer(alert);
|
||||
}
|
||||
|
||||
public void SendAllAlerts(Client client) {
|
||||
return; // Disables joining ongoing alerts (since it doesn't work properly).
|
||||
|
||||
foreach (AlertInfo alert in alerts) {
|
||||
if (alert.IsRunning()) StartAlert(alert, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void StartAlert(AlertInfo alert, Client? specificClient = null) {
|
||||
NetworkArray NewRoomVariables = new();
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_START, alertId++, isPersistent: true));
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_TYPE, alert.type, isPersistent: true));
|
||||
double duration = (alert.endTime - DateTime.Now).TotalSeconds;
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_LENGTH, alert.type == "1" ? alert.redAlertDuration : duration, isPersistent: true));
|
||||
if (alert.type == "1") {
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_TIMEOUT, duration, isPersistent: true));
|
||||
} else if (alert.type == "3") {
|
||||
alert.songId = random.Next(0, alert.songs);
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_SONG, (double)alert.songId, isPersistent: true));
|
||||
}
|
||||
NetworkPacket packet = Utils.VlNetworkPacket(NewRoomVariables, Id);
|
||||
if (specificClient is null) {
|
||||
RoomVariables = NewRoomVariables;
|
||||
Send(packet);
|
||||
Console.WriteLine("Started event " +alert + " in room " + Name);
|
||||
} else {
|
||||
specificClient.Send(packet);
|
||||
Console.WriteLine("Added " + specificClient.PlayerData.DiplayName + " to event " + alert + " with " + duration + " seconds remaining");
|
||||
}
|
||||
}
|
||||
|
||||
void ResetAlertTimer(AlertInfo alert) {
|
||||
System.Timers.Timer? timer = alert.timer;
|
||||
if (timer != null) {
|
||||
timer.Stop();
|
||||
timer.Close();
|
||||
}
|
||||
DateTime startTime = DateTime.Now.AddMilliseconds(random.Next(alert.minTime * 1000, alert.maxTime * 1000));
|
||||
DateTime endTime = startTime.AddSeconds(alert.duration);
|
||||
for (int i = 0; i < alerts.IndexOf(alert); i++) {
|
||||
// Prevent overlap between two events.
|
||||
if (alerts[i].Overlaps(endTime)) {
|
||||
startTime = alerts[i].endTime.AddSeconds(5);
|
||||
endTime = startTime.AddSeconds(alert.duration);
|
||||
}
|
||||
}
|
||||
timer = new System.Timers.Timer((startTime - DateTime.Now).TotalMilliseconds);
|
||||
timer.AutoReset = false;
|
||||
timer.Enabled = true;
|
||||
timer.Elapsed += (sender, e) => StartAlert(alert);
|
||||
timer.Elapsed += (sender, e) => ResetAlertTimer(alert);
|
||||
alert.timer = timer;
|
||||
Console.WriteLine("Event " + alert + " in " + Name + " scheduled for " + startTime.ToString("MM/dd/yyyy HH:mm:ss tt") + " (in " + (startTime - DateTime.Now).TotalSeconds + " seconds)");
|
||||
alert.startTime = startTime;
|
||||
alert.endTime = endTime;
|
||||
}
|
||||
|
||||
private const string REDALERT_START = "RA_S";
|
||||
private const string REDALERT_TYPE = "RA_A";
|
||||
private const string REDALERT_LENGTH = "RA_L";
|
||||
private const string REDALERT_TIMEOUT = "RA_T";
|
||||
private const string REDALERT_SONG = "RA_SO";
|
||||
|
||||
public class AlertInfo {
|
||||
public readonly string type;
|
||||
public readonly double duration;
|
||||
public readonly int minTime;
|
||||
public readonly int maxTime;
|
||||
public readonly int redAlertDuration;
|
||||
public readonly int songs;
|
||||
public int songId;
|
||||
|
||||
public DateTime startTime {
|
||||
get {
|
||||
return newStartTime;
|
||||
}
|
||||
set {
|
||||
oldStartTime = newStartTime;
|
||||
newStartTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime endTime {
|
||||
get {
|
||||
return newEndTime;
|
||||
}
|
||||
set {
|
||||
oldEndTime = newEndTime;
|
||||
newEndTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
private DateTime newStartTime;
|
||||
private DateTime newEndTime;
|
||||
private DateTime oldStartTime;
|
||||
private DateTime oldEndTime;
|
||||
|
||||
public System.Timers.Timer? timer = null;
|
||||
|
||||
public AlertInfo(string type, double duration = 20.0, int minTime = 30, int maxTime = 240, int redAlertDuration = 60, int songs = 16) {
|
||||
this.type = type;
|
||||
this.duration = duration;
|
||||
this.minTime = minTime;
|
||||
this.maxTime = maxTime;
|
||||
this.redAlertDuration = redAlertDuration;
|
||||
this.songs = songs;
|
||||
}
|
||||
|
||||
public bool Overlaps(DateTime time) {
|
||||
return (time >= oldStartTime && time <= oldEndTime);
|
||||
}
|
||||
|
||||
public bool IsRunning() {
|
||||
return Overlaps(DateTime.Now);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return type switch {
|
||||
"1" => "RedAlert",
|
||||
"2" => "DiscoAlert",
|
||||
"3" => "DanceOff",
|
||||
_ => type
|
||||
};
|
||||
}
|
||||
}
|
||||
internal virtual NetworkArray GetRoomVars() { return RoomVariables; }
|
||||
}
|
||||
|
191
src/Core/SpecialRoom.cs
Normal file
191
src/Core/SpecialRoom.cs
Normal file
@ -0,0 +1,191 @@
|
||||
using sodoffmmo.Data;
|
||||
|
||||
namespace sodoffmmo.Core;
|
||||
|
||||
public class SpecialRoom : Room {
|
||||
public double[] ambassadorGauges = new double[3]; // There is always a maximum of 3.
|
||||
System.Timers.Timer? ambassadorTimer;
|
||||
|
||||
public static void CreateRooms() {
|
||||
foreach (var room in Configuration.ServerConfiguration.RoomAlerts) {
|
||||
foreach (var alert in room.Value) {
|
||||
AlertInfo alertInfo = new AlertInfo(
|
||||
alert[0], // type
|
||||
float.Parse(alert[1], System.Globalization.CultureInfo.InvariantCulture.NumberFormat), // duration
|
||||
Int32.Parse(alert[2]), Int32.Parse(alert[3]), // start min - max for random start time
|
||||
Int32.Parse(alert[4]), Int32.Parse(alert[5]) // extra parameters for specific alarm types
|
||||
);
|
||||
Console.WriteLine($"Setup alert {alertInfo} for {room.Key}");
|
||||
(rooms.GetValueOrDefault(room.Key) as SpecialRoom ?? new SpecialRoom(room.Key)).AddAlert(alertInfo);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var room in Configuration.ServerConfiguration.AmbassadorRooms) {
|
||||
Console.WriteLine($"Setup Ambassador for {room}");
|
||||
(rooms.GetValueOrDefault(room) as SpecialRoom ?? new SpecialRoom(room)).InitAmbassador();
|
||||
}
|
||||
}
|
||||
|
||||
public SpecialRoom(string name) : base(name) {}
|
||||
|
||||
public void InitAmbassador() {
|
||||
for (int i=0;i<3;i++) ambassadorGauges[i] = Configuration.ServerConfiguration.AmbassadorGaugeStart;
|
||||
ambassadorTimer = new(Configuration.ServerConfiguration.AmbassadorGaugeDecayRate * 1000) {
|
||||
AutoReset = true,
|
||||
Enabled = true
|
||||
};
|
||||
ambassadorTimer.Elapsed += (sender, e) => {
|
||||
if (!Configuration.ServerConfiguration.AmbassadorGaugeDecayOnlyWhenInRoom || ClientsCount > 0) {
|
||||
for (int i=0;i<3;i++) ambassadorGauges[i] = Math.Max(0, ambassadorGauges[i]-1);
|
||||
Send(Utils.VlNetworkPacket(GetRoomVars(), Id));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal override NetworkArray GetRoomVars() {
|
||||
NetworkArray vars = new();
|
||||
vars.Add(NetworkArray.VlElement("COUNT", (int)Math.Round(ambassadorGauges[0]), isPersistent: true));
|
||||
vars.Add(NetworkArray.VlElement("COUNT2", (int)Math.Round(ambassadorGauges[1]), isPersistent: true));
|
||||
vars.Add(NetworkArray.VlElement("COUNT3", (int)Math.Round(ambassadorGauges[2]), isPersistent: true));
|
||||
for (int i=0;i<RoomVariables.Length;i++) vars.Add(RoomVariables[i]);
|
||||
return vars;
|
||||
}
|
||||
|
||||
private int alertId = -1;
|
||||
private Random random = new();
|
||||
|
||||
List<AlertInfo> alerts = new();
|
||||
|
||||
public void AddAlert(AlertInfo alert) {
|
||||
alerts.Add(alert);
|
||||
ResetAlertTimer(alert);
|
||||
}
|
||||
|
||||
public void SendAllAlerts(Client client) {
|
||||
return; // Disables joining ongoing alerts (since it doesn't work properly).
|
||||
|
||||
foreach (AlertInfo alert in alerts) {
|
||||
if (alert.IsRunning()) StartAlert(alert, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void StartAlert(AlertInfo alert, Client? specificClient = null) {
|
||||
NetworkArray NewRoomVariables = new();
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_START, alertId++, isPersistent: true));
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_TYPE, alert.type, isPersistent: true));
|
||||
double duration = (alert.endTime - DateTime.Now).TotalSeconds;
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_LENGTH, alert.type == "1" ? alert.redAlertDuration : duration, isPersistent: true));
|
||||
if (alert.type == "1") {
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_TIMEOUT, duration, isPersistent: true));
|
||||
} else if (alert.type == "3") {
|
||||
alert.songId = random.Next(0, alert.songs);
|
||||
NewRoomVariables.Add(NetworkArray.VlElement(REDALERT_SONG, (double)alert.songId, isPersistent: true));
|
||||
}
|
||||
NetworkPacket packet = Utils.VlNetworkPacket(NewRoomVariables, Id);
|
||||
if (specificClient is null) {
|
||||
RoomVariables = NewRoomVariables;
|
||||
Send(packet);
|
||||
RoomVariables = new();
|
||||
Console.WriteLine("Started event " +alert + " in room " + Name);
|
||||
} else {
|
||||
specificClient.Send(packet);
|
||||
Console.WriteLine("Added " + specificClient.PlayerData.DiplayName + " to event " + alert + " with " + duration + " seconds remaining");
|
||||
}
|
||||
}
|
||||
|
||||
void ResetAlertTimer(AlertInfo alert) {
|
||||
System.Timers.Timer? timer = alert.timer;
|
||||
if (timer != null) {
|
||||
timer.Stop();
|
||||
timer.Close();
|
||||
}
|
||||
DateTime startTime = DateTime.Now.AddMilliseconds(random.Next(alert.minTime * 1000, alert.maxTime * 1000));
|
||||
DateTime endTime = startTime.AddSeconds(alert.duration);
|
||||
for (int i = 0; i < alerts.IndexOf(alert); i++) {
|
||||
// Prevent overlap between two events.
|
||||
if (alerts[i].Overlaps(endTime)) {
|
||||
startTime = alerts[i].endTime.AddSeconds(5);
|
||||
endTime = startTime.AddSeconds(alert.duration);
|
||||
}
|
||||
}
|
||||
timer = new System.Timers.Timer((startTime - DateTime.Now).TotalMilliseconds);
|
||||
timer.AutoReset = false;
|
||||
timer.Enabled = true;
|
||||
timer.Elapsed += (sender, e) => StartAlert(alert);
|
||||
timer.Elapsed += (sender, e) => ResetAlertTimer(alert);
|
||||
alert.timer = timer;
|
||||
Console.WriteLine("Event " + alert + " in " + Name + " scheduled for " + startTime.ToString("MM/dd/yyyy HH:mm:ss tt") + " (in " + (startTime - DateTime.Now).TotalSeconds + " seconds)");
|
||||
alert.startTime = startTime;
|
||||
alert.endTime = endTime;
|
||||
}
|
||||
|
||||
private const string REDALERT_START = "RA_S";
|
||||
private const string REDALERT_TYPE = "RA_A";
|
||||
private const string REDALERT_LENGTH = "RA_L";
|
||||
private const string REDALERT_TIMEOUT = "RA_T";
|
||||
private const string REDALERT_SONG = "RA_SO";
|
||||
|
||||
public class AlertInfo {
|
||||
public readonly string type;
|
||||
public readonly double duration;
|
||||
public readonly int minTime;
|
||||
public readonly int maxTime;
|
||||
public readonly int redAlertDuration;
|
||||
public readonly int songs;
|
||||
public int songId;
|
||||
|
||||
public DateTime startTime {
|
||||
get {
|
||||
return newStartTime;
|
||||
}
|
||||
set {
|
||||
oldStartTime = newStartTime;
|
||||
newStartTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime endTime {
|
||||
get {
|
||||
return newEndTime;
|
||||
}
|
||||
set {
|
||||
oldEndTime = newEndTime;
|
||||
newEndTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
private DateTime newStartTime;
|
||||
private DateTime newEndTime;
|
||||
private DateTime oldStartTime;
|
||||
private DateTime oldEndTime;
|
||||
|
||||
public System.Timers.Timer? timer = null;
|
||||
|
||||
public AlertInfo(string type, double duration = 20.0, int minTime = 30, int maxTime = 240, int redAlertDuration = 60, int songs = 16) {
|
||||
this.type = type;
|
||||
this.duration = duration;
|
||||
this.minTime = minTime;
|
||||
this.maxTime = maxTime;
|
||||
this.redAlertDuration = redAlertDuration;
|
||||
this.songs = songs;
|
||||
}
|
||||
|
||||
public bool Overlaps(DateTime time) {
|
||||
return (time >= oldStartTime && time <= oldEndTime);
|
||||
}
|
||||
|
||||
public bool IsRunning() {
|
||||
return Overlaps(DateTime.Now);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return type switch {
|
||||
"1" => "RedAlert",
|
||||
"2" => "DiscoAlert",
|
||||
"3" => "DanceOff",
|
||||
_ => type
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -29,18 +29,7 @@ public class Server {
|
||||
listener.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 0);
|
||||
listener.Bind(new IPEndPoint(ipAddress, port));
|
||||
|
||||
foreach (var room in Configuration.ServerConfiguration.RoomAlerts) {
|
||||
foreach (var alert in room.Value) {
|
||||
Room.AlertInfo alertInfo = new Room.AlertInfo(
|
||||
alert[0], // type
|
||||
float.Parse(alert[1], System.Globalization.CultureInfo.InvariantCulture.NumberFormat), // duration
|
||||
Int32.Parse(alert[2]), Int32.Parse(alert[3]), // start min - max for random start time
|
||||
Int32.Parse(alert[4]), Int32.Parse(alert[5]) // extra parameters for specific alarm types
|
||||
);
|
||||
Console.WriteLine($"Setup alert {alertInfo} for {room.Key}");
|
||||
Room.GetOrAdd(room.Key).AddAlert(alertInfo);
|
||||
}
|
||||
}
|
||||
SpecialRoom.CreateRooms();
|
||||
|
||||
await Listen(listener);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user