mirror of
https://github.com/AndrioCelos/TableturfBattleApp.git
synced 2026-08-28 05:43:59 -05:00
Target .NET 8.0
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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) { }
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>());
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user