Target .NET 8.0

This commit is contained in:
Andrio Celos
2023-11-23 12:24:57 +11:00
parent 6382f6bd1f
commit 5f184795cb
15 changed files with 100 additions and 167 deletions

View File

@@ -1,13 +1,11 @@
using System.Collections.ObjectModel;
using Newtonsoft.Json;
namespace TableturfBattleServer;
public static class CardDatabase {
private const Space I = Space.Ink1;
private const Space S = Space.SpecialInactive1;
private static readonly Card[] cards = new Card[] {
private static readonly Card[] cards = [
new( 1, "Hero Shot", Rarity.Fresh, 1f, "HeroShooter", new Space[,] {
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, I, I, 0, I, 0, 0 },
@@ -2218,7 +2216,7 @@ public static class CardDatabase {
{ 0, 0, 0, 0, 0, I, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }
}) { InkColour1 = new(84, 142, 122), InkColour2 = new(193, 111, 98) },
};
];
private static readonly Dictionary<int, Card> byAltNumber;

View File

@@ -2,39 +2,23 @@
namespace TableturfBattleServer.DTO;
internal class WebSocketPayload<T> {
internal class WebSocketPayload<T>(string eventName, T payload) {
[JsonProperty("event")]
public string EventName;
public string EventName = eventName ?? throw new ArgumentNullException(nameof(eventName));
[JsonProperty("data")]
public T Payload;
public WebSocketPayload(string eventName, T payload) {
this.EventName = eventName ?? throw new ArgumentNullException(nameof(eventName));
this.Payload = payload;
}
public T Payload = payload;
}
internal class WebSocketPayloadWithPlayerData<T> : WebSocketPayload<T> {
public PlayerData? PlayerData;
public WebSocketPayloadWithPlayerData(string eventName, T payload, PlayerData? playerData) : base(eventName, payload)
=> this.PlayerData = playerData;
internal class WebSocketPayloadWithPlayerData<T>(string eventName, T payload, PlayerData? playerData) : WebSocketPayload<T>(eventName, payload) {
public PlayerData? PlayerData = playerData;
}
public class PlayerData {
public int PlayerIndex;
public Card[]? Hand;
public Deck? Deck;
public Move? Move;
public List<int>? CardsUsed;
public StageSelectionPrompt? StageSelectionPrompt;
public class PlayerData(int playerIndex, Card[]? hand, Deck? deck, Move? move, List<int>? cardsUsed, StageSelectionPrompt? stageSelectionPrompt) {
public int PlayerIndex = playerIndex;
public Card[]? Hand = hand;
public Deck? Deck = deck;
public Move? Move = move;
public List<int>? CardsUsed = cardsUsed;
public StageSelectionPrompt? StageSelectionPrompt = stageSelectionPrompt;
public PlayerData(int playerIndex, Card[]? hand, Deck? deck, Move? move, List<int>? cardsUsed, StageSelectionPrompt? stageSelectionPrompt) {
this.PlayerIndex = playerIndex;
this.Hand = hand;
this.Deck = deck;
this.Move = move;
this.CardsUsed = cardsUsed;
this.StageSelectionPrompt = stageSelectionPrompt;
}
public PlayerData(int playerIndex, Player player) : this(playerIndex, player.Hand, player.CurrentGameData.Deck, player.Move, player.CardsUsed, player.StageSelectionPrompt) { }
}

View File

@@ -1,22 +1,15 @@
using Newtonsoft.Json;
namespace TableturfBattleServer;
public class Deck : IEquatable<Deck> {
public class Deck(string name, int sleeves, Card[] cards, int[] levels) : IEquatable<Deck> {
[JsonProperty]
internal string Name;
internal string Name = name ?? throw new ArgumentNullException(nameof(name));
[JsonProperty]
internal int Sleeves;
internal int Sleeves = sleeves;
[JsonProperty]
internal Card[] Cards;
internal Card[] Cards = cards ?? throw new ArgumentNullException(nameof(cards));
[JsonProperty]
internal int[] Upgrades;
public Deck(string name, int sleeves, Card[] cards, int[] levels) {
this.Name = name ?? throw new ArgumentNullException(nameof(name));
this.Sleeves = sleeves;
this.Cards = cards ?? throw new ArgumentNullException(nameof(cards));
this.Upgrades = levels ?? throw new ArgumentNullException(nameof(levels));
}
internal int[] Upgrades = levels ?? throw new ArgumentNullException(nameof(levels));
public bool Equals(Deck? other)
=> other is not null && this.Name == other.Name && this.Sleeves == other.Sleeves && this.Cards.SequenceEqual(other.Cards) && this.Upgrades.SequenceEqual(other.Upgrades);

View File

@@ -2,15 +2,9 @@
using Newtonsoft.Json;
namespace TableturfBattleServer;
public readonly struct Error {
public readonly struct Error(HttpStatusCode httpStatusCode, string code, string description) {
[JsonIgnore]
public HttpStatusCode HttpStatusCode { get; }
public string Code { get; }
public string Description { get; }
public Error(HttpStatusCode httpStatusCode, string code, string description) {
this.HttpStatusCode = httpStatusCode;
this.Code = code ?? throw new ArgumentNullException(nameof(code));
this.Description = description ?? throw new ArgumentNullException(nameof(description));
}
public HttpStatusCode HttpStatusCode { get; } = httpStatusCode;
public string Code { get; } = code ?? throw new ArgumentNullException(nameof(code));
public string Description { get; } = description ?? throw new ArgumentNullException(nameof(description));
}

View File

@@ -2,17 +2,16 @@
using System.Net;
using System.Text;
using Newtonsoft.Json;
using WebSocketSharp.Server;
namespace TableturfBattleServer;
public class Game {
public class Game(int maxPlayers) {
[JsonIgnore]
public Guid ID { get; } = Guid.NewGuid();
public GameState State { get; set; }
public int TurnNumber { get; set; }
public List<Player> Players { get; } = new(4);
public int MaxPlayers { get; set; }
public int MaxPlayers { get; set; } = maxPlayers;
[JsonProperty("stage")]
public int? StageIndex { get; private set; }
public Space[,]? Board { get; private set; }
@@ -30,16 +29,14 @@ public class Game {
public required StageSelectionRules StageSelectionRuleAfterDraw { get; set; }
public bool ForceSameDeckAfterDraw { get; set; }
public List<int> StruckStages = new();
public List<int> StruckStages = [];
[JsonIgnore]
internal List<Deck> deckCache = new();
internal List<Deck> deckCache = [];
[JsonIgnore]
internal List<int> setStages = new();
internal List<int> setStages = [];
public Game(int maxPlayers) => this.MaxPlayers = maxPlayers;
private static readonly PlayerColours[] Colours = new PlayerColours[] {
private static readonly PlayerColours[] Colours = [
new(new(0xf2200d), new(0xff8c1a), new(0xffd5cc), false), // Red
new(new(0xf2740d), new(0xff4000), new(0xffcc99), true), // Orange
new(new(0xecf901), new(0xfa9e00), new(0xf9f91f), true), // Yellow
@@ -49,7 +46,7 @@ public class Game {
new(new(0x4a5cfc), new(0x01edfe), new(0xd5e1e1), false), // Blue
new(new(0xa106ef), new(0xff00ff), new(0xffb3ff), false), // Purple
new(new(0xf906e0), new(0x8006f9), new(0xebb4fd), true), // Magenta
};
];
public bool TryAddPlayer(Player player, out int playerIndex, out Error error) {
lock (this.Players) {
@@ -140,7 +137,7 @@ public class Game {
}
public bool CanPlay(int playerIndex, Card card, int x, int y, int rotation, bool isSpecialAttack) {
if (card is null) throw new ArgumentNullException(nameof(card));
ArgumentNullException.ThrowIfNull(card);
if (this.Board is null || this.Players[playerIndex].CurrentGameData is not SingleGameData gameData) return false;
if (isSpecialAttack && (gameData.SpecialPoints < card.SpecialCost))
@@ -157,7 +154,8 @@ public class Game {
|| y2 < 0 || y2 > this.Board.GetUpperBound(1))
return false; // Out of bounds.
switch (this.Board[x2, y2]) {
case Space.Wall: case Space.OutOfBounds:
case Space.Wall:
case Space.OutOfBounds:
return false;
case >= Space.SpecialInactive1:
return false; // Can't overlap special spaces ever.
@@ -243,7 +241,7 @@ public class Game {
this.LockInStage(legalStages[random.Next(legalStages.Count)]);
} else {
if (player.selectedStages!.First() >= 0)
this.LockInStage(player.selectedStages.First());
this.LockInStage(player.selectedStages!.First());
else {
var legalStages = Enumerable.Range(0, StageDatabase.Stages.Count).Except(rule.BannedStages).Except(player.StageSelectionPrompt!.Value.StruckStages).ToList();
this.LockInStage(legalStages[random.Next(legalStages.Count)]);
@@ -253,7 +251,7 @@ public class Game {
break;
}
case StageSelectionMethod.Strike: {
var player = this.Players.FirstOrDefault(p => p.StageSelectionPrompt != null && p.StageSelectionPrompt?.PromptType != StageSelectionPromptType.Wait);
var player = this.Players.FirstOrDefault(p => p.StageSelectionPrompt != null && p.StageSelectionPrompt?.PromptType != StageSelectionPromptType.Wait) ?? throw new InvalidOperationException("Couldn't find striking player?!");
switch (player.StageSelectionPrompt!.Value.PromptType) {
case StageSelectionPromptType.VoteOrder:
// Choose who will strike first.
@@ -287,7 +285,7 @@ public class Game {
break;
case StageSelectionPromptType.Choose:
if (player.selectedStages!.First() >= 0)
this.LockInStage(player.selectedStages.First());
this.LockInStage(player.selectedStages!.First());
else {
var legalStages = Enumerable.Range(0, StageDatabase.Stages.Count).Except(rule.BannedStages).Except(player.StageSelectionPrompt!.Value.StruckStages).ToList();
this.LockInStage(legalStages[random.Next(legalStages.Count)]);
@@ -482,7 +480,7 @@ public class Game {
}
}
} else if (this.State is GameState.GameEnded or GameState.SetEnded && this.Players.All(p => p.Move != null)) {
SetupNextGame();
this.SetupNextGame();
}
}
@@ -547,9 +545,9 @@ public class Game {
this.LockInStage(legalStages[0]);
break;
}
var bannedStages = legalStages.Count == 0 ? Array.Empty<int>() : rule.BannedStages;
var bannedStages = legalStages.Count == 0 ? [] : rule.BannedStages;
foreach (var player in this.Players) {
player.StageSelectionPrompt = new() { PromptType = StageSelectionPromptType.Vote, BannedStages = bannedStages, StruckStages = Array.Empty<int>() };
player.StageSelectionPrompt = new() { PromptType = StageSelectionPromptType.Vote, BannedStages = bannedStages, StruckStages = [] };
}
break;
}

View File

@@ -1,24 +1,14 @@
using System.ComponentModel;
namespace TableturfBattleServer;
public class Move {
public Card Card { get; }
public bool IsPass { get; }
public int X { get; }
public int Y { get; }
public int Rotation { get; }
public bool IsSpecialAttack { get; }
public bool IsTimeout { get; }
public Move(Card card, bool isPass, int x, int y, int rotation, bool isSpecialAttack, bool isTimeout) {
this.Card = card ?? throw new ArgumentNullException(nameof(card));
this.IsPass = isPass;
this.X = x;
this.Y = y;
this.Rotation = rotation;
this.IsSpecialAttack = isSpecialAttack;
this.IsTimeout = isTimeout;
}
public class Move(Card card, bool isPass, int x, int y, int rotation, bool isSpecialAttack, bool isTimeout) {
public Card Card { get; } = card ?? throw new ArgumentNullException(nameof(card));
public bool IsPass { get; } = isPass;
public int X { get; } = x;
public int Y { get; } = y;
public int Rotation { get; } = rotation;
public bool IsSpecialAttack { get; } = isSpecialAttack;
public bool IsTimeout { get; } = isTimeout;
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeX() => !this.IsPass;

View File

@@ -2,9 +2,9 @@
namespace TableturfBattleServer;
public class Placement {
public List<int> Players { get; } = new();
public List<int> Players { get; } = [];
[JsonConverter(typeof(SpacesAffectedDictionaryConverter))]
public Dictionary<Point, Space> SpacesAffected { get; } = new();
public Dictionary<Point, Space> SpacesAffected { get; } = [];
internal class SpacesAffectedDictionaryConverter : JsonConverter<Dictionary<Point, Space>> {
public override Dictionary<Point, Space>? ReadJson(JsonReader reader, Type objectType, Dictionary<Point, Space>? existingValue, bool hasExistingValue, JsonSerializer serializer) {
@@ -12,8 +12,7 @@ public class Placement {
return list?.ToDictionary(o => o.space, o => o.newState);
}
public override void WriteJson(JsonWriter writer, Dictionary<Point, Space>? value, JsonSerializer serializer) {
serializer.Serialize(writer, value?.Select(e => new { space = e.Key, newState = e.Value }));
}
public override void WriteJson(JsonWriter writer, Dictionary<Point, Space>? value, JsonSerializer serializer)
=> serializer.Serialize(writer, value?.Select(e => new { space = e.Key, newState = e.Value }));
}
}

View File

@@ -1,17 +1,17 @@
using Newtonsoft.Json;
namespace TableturfBattleServer;
public class Player {
public string Name { get; }
public class Player(Game game, string name, Guid token) {
public string Name { get; } = name ?? throw new ArgumentNullException(nameof(name));
[JsonIgnore]
public Guid Token { get; }
public Guid Token { get; } = token;
public Colour Colour { get; set; }
public Colour SpecialColour { get; set; }
public Colour SpecialAccentColour { get; set; }
public bool UIBaseColourIsSpecialColour { get; set; }
[JsonIgnore]
internal List<TableturfWebSocketBehaviour> Connections { get; } = new();
internal List<TableturfWebSocketBehaviour> Connections { get; } = [];
[JsonIgnore]
public DateTime? DisconnectedAt { get; set; }
public bool IsOnline => this.DisconnectedAt == null;
@@ -19,7 +19,7 @@ public class Player {
public StageSelectionPrompt? StageSelectionPrompt { get; set; }
[JsonIgnore]
private readonly Game game;
private readonly Game game = game ?? throw new ArgumentNullException(nameof(game));
[JsonIgnore]
internal readonly List<int> CardsUsed = new(12);
[JsonIgnore]
@@ -32,7 +32,7 @@ public class Player {
public int GamesWon { get; set; }
[JsonIgnore]
internal List<SingleGameData> Games { get; } = new() { new() };
internal List<SingleGameData> Games { get; } = [new()];
[JsonIgnore]
public SingleGameData CurrentGameData => this.Games[^1];
@@ -54,13 +54,7 @@ public class Player {
[JsonIgnore]
internal ICollection<int>? selectedStages;
internal static readonly int[] RandomStageSelection = new[] { -1 };
public Player(Game game, string name, Guid token) {
this.game = game ?? throw new ArgumentNullException(nameof(game));
this.Name = name ?? throw new ArgumentNullException(nameof(name));
this.Token = token;
}
internal static readonly int[] RandomStageSelection = [-1];
public void ClearMoves() {
this.Move = null;

View File

@@ -1,10 +1,5 @@
namespace TableturfBattleServer;
public struct Point {
public int X;
public int Y;
public Point(int x, int y) {
this.X = x;
this.Y = y;
}
public struct Point(int x, int y) {
public int X = x;
public int Y = y;
}

View File

@@ -18,8 +18,8 @@ namespace TableturfBattleServer;
internal class Program {
internal static HttpServer? httpServer;
internal static Dictionary<Guid, Game> games = new();
internal static Dictionary<Guid, Game> inactiveGames = new();
internal static Dictionary<Guid, Game> games = [];
internal static Dictionary<Guid, Game> inactiveGames = [];
internal static readonly Timer timer = new(1000);
private static bool lockdown;
@@ -417,7 +417,7 @@ internal class Program {
SetErrorResponse(e.Response, new(HttpStatusCode.BadRequest, "InvalidDeckCards", "Missing deck cards."));
return;
}
var array = deckString.Split(new[] { ',', '+', ' ' }, 15);
var array = deckString.Split([',', '+', ' '], 15);
if (array.Length != 15) {
SetErrorResponse(e.Response, new(HttpStatusCode.UnprocessableEntity, "InvalidDeckCards", "Invalid deck list."));
return;
@@ -425,7 +425,7 @@ internal class Program {
int[]? upgrades = null;
if (d.TryGetValue("deckUpgrades", out var deckUpgradesString)) {
upgrades = new int[15];
var array2 = deckUpgradesString.Split(new[] { ',', '+', ' ' }, 15);
var array2 = deckUpgradesString.Split([',', '+', ' '], 15);
for (var i = 0; i < 15; i++) {
if (int.TryParse(array2[i], out var j) && i is >= 0 and <= 2)
upgrades[i] = j;
@@ -644,9 +644,9 @@ internal class Program {
using var reader = new StreamReader(stream);
var s = reader.ReadToEnd();
return s != ""
? s.Split(new[] { '&' }).Select(s => s.Split('=')).Select(a => a.Length == 2 ? a : throw new ArgumentException("Invalid form data"))
? s.Split(['&']).Select(s => s.Split('=')).Select(a => a.Length == 2 ? a : throw new ArgumentException("Invalid form data"))
.ToDictionary(a => HttpUtility.UrlDecode(a[0]), a => HttpUtility.UrlDecode(a[1]))
: new();
: [];
}
private static void SetStaticResponse(HttpListenerRequest request, HttpListenerResponse response, string jsonContent, string eTag, DateTime lastModified) {

View File

@@ -1,10 +1,10 @@
using Newtonsoft.Json;
namespace TableturfBattleServer;
public class Stage {
public string Name { get; }
public class Stage(string name, Space[,] grid, Point[][] startSpaces) {
public string Name { get; } = name ?? throw new ArgumentNullException(nameof(name));
[JsonProperty]
internal readonly Space[,] grid;
internal readonly Space[,] grid = grid ?? throw new ArgumentNullException(nameof(grid));
/// <summary>
/// The lists of starting spaces on this stage.
/// </summary>
@@ -13,11 +13,5 @@ public class Stage {
/// For example, if there is a list of 3 and a list of 4, the list of 3 will be used for 2 or 3 players, and the list of 4 will be used for 4 players.
/// </remarks>
[JsonProperty]
internal readonly Point[][] startSpaces;
public Stage(string name, Space[,] grid, Point[][] startSpaces) {
this.Name = name ?? throw new ArgumentNullException(nameof(name));
this.grid = grid ?? throw new ArgumentNullException(nameof(grid));
this.startSpaces = startSpaces ?? throw new ArgumentNullException(nameof(startSpaces));
}
internal readonly Point[][] startSpaces = startSpaces ?? throw new ArgumentNullException(nameof(startSpaces));
}

View File

@@ -1,17 +1,15 @@
using System.Collections.ObjectModel;
using Newtonsoft.Json;
namespace TableturfBattleServer;
internal class StageDatabase {
private const Space E = Space.Empty;
private const Space o = Space.OutOfBounds;
private static readonly Stage[] stages = new Stage[] {
new("Main Street", new Space[9, 26], new[] {
new Point[] { new(4, 22), new(4, 3), new(4, 13) },
new Point[] { new(2, 22), new(6, 3), new(6, 22), new(2, 3) }
}),
private static readonly Stage[] stages = [
new("Main Street", new Space[9, 26], [
[new(4, 22), new(4, 3), new(4, 13)],
[new(2, 22), new(6, 3), new(6, 22), new(2, 3)]
]),
new("Thunder Point", new Space[,] {
{ o, o, o, o, o, o, o, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E },
{ o, o, o, o, o, o, o, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E },
@@ -29,10 +27,10 @@ internal class StageDatabase {
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, o, o, o, o, o },
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, o, o, o, o, o },
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, o, o, o, o, o, o, o },
}, new[] {
new Point[] { new(3, 18), new(12, 3), new(7, 11) },
new Point[] { new(3, 18), new(12, 3), new(12, 11), new(3, 10) },
}),
}, [
[new(3, 18), new(12, 3), new(7, 11)],
[new(3, 18), new(12, 3), new(12, 11), new(3, 10)],
]),
new("X Marks the Garden", new Space[,] {
{ o, o, o, o, o, o, o, o, E, E, E, E, E, E, E, o, o, o, o, o, o, o, o },
{ o, o, o, o, o, o, o, o, E, E, E, E, E, E, E, o, o, o, o, o, o, o, o },
@@ -53,8 +51,8 @@ internal class StageDatabase {
{ o, o, o, o, o, o, o, o, E, E, E, E, E, E, E, o, o, o, o, o, o, o, o },
{ o, o, o, o, o, o, o, o, E, E, E, E, E, E, E, o, o, o, o, o, o, o, o },
{ o, o, o, o, o, o, o, o, E, E, E, E, E, E, E, o, o, o, o, o, o, o, o },
}, new[] { new Point[] { new(9, 19), new(x: 9, 3), new(15, 11), new(3, 11) } }),
new("Square Squared", new Space[15, 15], new[] { new Point[] { new(3, 11), new(11, 3), new(11, 11), new(3, 3) }}),
}, [[new(9, 19), new(x: 9, 3), new(15, 11), new(3, 11)]]),
new("Square Squared", new Space[15, 15], [[new(3, 11), new(11, 3), new(11, 11), new(3, 3)]]),
new("Lakefront Property", new Space[,] {
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, },
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, },
@@ -72,7 +70,7 @@ internal class StageDatabase {
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, },
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, },
{ E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, },
}, new[] { new Point[] { new(3, 12), new(12, 3), new(12, 12), new(3, 3) }}),
}, [[new(3, 12), new(12, 3), new(12, 12), new(3, 3)]]),
new("Double Gemini", new Space[,] {
{ o, o, o, o, o, o, o, o, E, o, o, o, o, o, o, o, E, o, o, o, o, o, o, o, o },
{ o, o, o, o, o, o, o, E, E, E, o, o, o, o, o, E, E, E, o, o, o, o, o, o, o },
@@ -91,10 +89,10 @@ internal class StageDatabase {
{ o, o, o, o, o, o, E, E, E, E, E, o, o, o, E, E, E, E, E, o, o, o, o, o, o },
{ o, o, o, o, o, o, o, E, E, E, o, o, o, o, o, E, E, E, o, o, o, o, o, o, o },
{ o, o, o, o, o, o, o, o, E, o, o, o, o, o, o, o, E, o, o, o, o, o, o, o, o },
}, new[] {
new Point[] { new(8, 19), new(8, 5), new(8, 12) },
new Point[] { new(5, 16), new(11, 8), new(11, 16), new(5, 8) }
}),
}, [
[new(8, 19), new(8, 5), new(8, 12)],
[new(5, 16), new(11, 8), new(11, 16), new(5, 8)]
]),
new("River Drift", new Space[,] {
{ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, E, E, E, E, E, E, E },
{ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, E, E, E, E, E, E, E },
@@ -113,12 +111,12 @@ internal class StageDatabase {
{ E, E, E, E, E, E, E, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o },
{ E, E, E, E, E, E, E, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o },
{ E, E, E, E, E, E, E, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o },
}, new[] {
new Point[] { new(3, 21), new(13, 3), new(8, 12) },
new Point[] { new(3, 21), new(13, 3), new(8, 16), new(8, 8) }
}),
new("Box Seats", new Space[10, 10], new[] { new Point[] { new(2, 7), new(7, 2), new(7, 7), new(2, 2) }}),
};
}, [
[new(3, 21), new(13, 3), new(8, 12)],
[new(3, 21), new(13, 3), new(8, 16), new(8, 8)]
]),
new("Box Seats", new Space[10, 10], [[new(2, 7), new(7, 2), new(7, 7), new(2, 2)]]),
];
public static Version Version { get; } = new(1, 2, 0, 1);
public static DateTime LastModified { get; } = new(2023, 4, 12, 23, 0, 0, DateTimeKind.Utc);

View File

@@ -1,13 +1,8 @@
namespace TableturfBattleServer;
public class StageSelectionRules {
public StageSelectionMethod Method { get; set; }
public int[] BannedStages { get; set; }
public StageSelectionRules(StageSelectionMethod method, int[]? bannedStages) {
this.Method = method;
this.BannedStages = bannedStages ?? Array.Empty<int>();
}
public class StageSelectionRules(StageSelectionMethod method, int[]? bannedStages) {
public StageSelectionMethod Method { get; set; } = method;
public int[] BannedStages { get; set; } = bannedStages ?? Array.Empty<int>();
public static StageSelectionRules Default { get; } = new(StageSelectionMethod.Vote, Array.Empty<int>());
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageProjectUrl>https://github.com/AndrioCelos/TableturfBattleApp</PackageProjectUrl>

View File

@@ -1,5 +1,4 @@
using System.Web;
using Newtonsoft.Json;
using WebSocketSharp.Server;
namespace TableturfBattleServer;
@@ -36,7 +35,9 @@ internal class TableturfWebSocketBehaviour : WebSocketBehavior {
this.Send(JsonUtils.Serialise(new DTO.WebSocketPayloadWithPlayerData<Game?>("sync", null, null)));
}
protected override void OnClose(WebSocketSharp.CloseEventArgs e) => this.Game?.RemoveConnection(this.Player, this);
protected override void OnClose(WebSocketSharp.CloseEventArgs e) {
if (this.Player != null) this.Game?.RemoveConnection(this.Player, this);
}
internal void SendInternal(string data) => this.Send(data);
}