sledgemapper/SignalRChat/SignalRChat/Hubs/ChatHub.cs

207 lines
No EOL
6.1 KiB
C#

using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SignalRChat.Hubs
{
public struct Overlay
{
public int X { get; set; }
public int Y { get; set; }
public int ID { get; set; }
public bool Intersection { get; set; }
public int Rotation { get; set; }
}
public struct Tile
{
public int X { get; set; }
public int Y { get; set; }
public int ID { get; set; }
public int Rotation { get; set; }
}
public struct Wall
{
public int X { get; set; }
public int Y { get; set; }
public int ID { get; set; }
public int Rotation { get; set; }
}
public class Player
{
public string ConnectionId { get; set; }
public string Color { get; set; }
public Tile Position { get; set; }
}
public class SessionData
{
public SessionData()
{
Map = new List<Tile>();
Overlays = new List<Overlay>();
Walls = new List<Wall>();
Players = new List<Player>();
Colors = new List<string>();
}
public List<Tile> Map { get; set; }
public List<Wall> Walls { get; set; }
public List<Overlay> Overlays { get; set; }
public bool IsValid { get; set; }
public List<Player> Players { get; set; }
public List<string> Colors;
}
public class ChatHub : Hub
{
private static Dictionary<string, SessionData> _sessions = new Dictionary<string, SessionData>();
public List<string> Colors = new List<string>{"CC0000",
"CC3300",
"FFCC00",
"009900",
"006666",
"0066FF",
"0000CC",
"663399",
"CC0099"};
public async Task SendMessage(string user, string message, string sessionName)
{
await Clients.Group(sessionName).SendAsync("ReceiveMessage", user, message);
}
public async Task NewTile(string sessionName, Tile tile)
{
if (_sessions[sessionName].Map.Contains(tile))
{
_sessions[sessionName].Map.Remove(tile);
}
await Clients.Group(sessionName).SendAsync("NewTile", tile);
}
public async Task NewWall(string sessionName, Wall tile)
{
if (_sessions[sessionName].Walls.Contains(tile))
{
_sessions[sessionName].Walls.Remove(tile);
}
await Clients.Group(sessionName).SendAsync("NewWall", tile);
}
public async Task NewOverlay(string sessionName, Overlay tile)
{
if (_sessions[sessionName].Overlays.Contains(tile))
{
_sessions[sessionName].Overlays.Remove(tile);
}
await Clients.Group(sessionName).SendAsync(" ", tile);
}
public async Task DeleteTile(string sessionName, Tile tile)
{
if (_sessions[sessionName].Map.Contains(tile))
{
_sessions[sessionName].Map.Remove(tile);
}
await Clients.Group(sessionName).SendAsync("DeleteTile", tile);
}
public async Task DeleteWall(string sessionName, Wall tile)
{
if (_sessions[sessionName].Walls.Contains(tile))
{
_sessions[sessionName].Walls.Remove(tile);
}
await Clients.Group(sessionName).SendAsync("DeleteWall", tile);
}
public async Task DeleteOverlay(string sessionName, Overlay tile)
{
if (_sessions[sessionName].Overlays.Contains(tile))
{
_sessions[sessionName].Overlays.Remove(tile);
}
await Clients.Group(sessionName).SendAsync("DeleteOverlay", tile);
}
public async Task<SessionData> NewSession(string sessionName)
{
var session = new SessionData();
session.Colors = new List<string>(Colors);
session.Colors.Shuffle();
var player = new Player { Position = new Tile { X = 0, Y = 0 }, ConnectionId = Context.ConnectionId, Color = session.Colors[0] };
session.Players.Add(player);
_sessions.Add(sessionName, session);
await Clients.Group(sessionName).SendAsync("NewPlayer", player);
await Groups.AddToGroupAsync(Context.ConnectionId, sessionName);
return session;
}
public async Task<SessionData> JoinSession(string sessionName)
{
if (_sessions.ContainsKey(sessionName))
{
var session = _sessions[sessionName];
var player = new Player { Position = new Tile { X = 0, Y = 0 }, ConnectionId = Context.ConnectionId, Color = session.Colors[session.Players.Count] };
session.Players.Add(player);
await Groups.AddToGroupAsync(Context.ConnectionId, sessionName);
return session;
}
else
{
return null;
}
}
public async Task UpdatePosition(string sessionName, Tile tile)
{
var player = _sessions[sessionName].Players.First(m => m.ConnectionId == Context.ConnectionId);
player.Position = tile;
await Clients.Group(sessionName).SendAsync("PlayerUpdate", player);
}
public async Task<SessionData> Refresh(string sessionName)
{
return _sessions[sessionName];
}
public async Task Sync(string sessionName, List<Tile> map)
{
_sessions[sessionName].Map = map;
await Clients.Group(sessionName).SendAsync("UpdateMap", map);
}
}
public static class ExtensionMethods
{
private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
}