├── GameDatabase ├── .gitignore ├── RedisCache │ └── RedisDb.cs ├── GameDatabase.csproj └── Mongodb │ ├── Interfaces │ └── IGameDB.cs │ └── Handlers │ ├── MongoDb.cs │ └── MongoHandler.cs ├── Youtube-GameOnlineServer ├── .gitignore ├── Rooms │ ├── Constants │ │ └── RoomType.cs │ ├── Interfaces │ │ ├── IRoomManager.cs │ │ └── IBaseRoom.cs │ └── Handlers │ │ ├── TikTakToeRoom.cs │ │ ├── Lobby.cs │ │ ├── RoomManager.cs │ │ └── BaseRoom.cs ├── Applications │ ├── Messaging │ │ ├── IMessageManager.cs │ │ ├── Constants │ │ │ ├── CreatRoomData.cs │ │ │ ├── LoginData.cs │ │ │ ├── RegisterData.cs │ │ │ ├── RoomInfo.cs │ │ │ └── UserInfo.cs │ │ ├── IMessage.cs │ │ ├── WsTags.cs │ │ └── WsMessage.cs │ ├── Interfaces │ │ ├── IWsGameServer.cs │ │ ├── IPlayerManager.cs │ │ └── IPlayer.cs │ └── Handlers │ │ ├── GameHelper.cs │ │ ├── PlayersManager.cs │ │ ├── WsGameServer.cs │ │ └── Player.cs ├── GameModels │ ├── RoomModel.cs │ ├── Interfaces │ │ └── IDbHandler.cs │ ├── Base │ │ └── BaseModel.cs │ ├── User.cs │ └── Handlers │ │ ├── RoomHandler.cs │ │ └── UserHandler.cs ├── Logging │ ├── IGameLogger.cs │ ├── GameLogger.cs │ └── TypeNameHelper.cs ├── .dockerignore ├── Dockerfile ├── Youtube-GameOnlineServer.csproj └── Program.cs ├── .idea └── .idea.Youtube-GameOnlineServer │ └── .idea │ ├── .name │ ├── vcs.xml │ ├── indexLayout.xml │ ├── misc.xml │ ├── .gitignore │ └── dataSources.xml ├── .gitignore ├── global.json ├── Readme.md ├── Youtube-GameOnlineServer.sln.DotSettings.user └── Youtube-GameOnlineServer.sln /GameDatabase/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /obj/ -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/.gitignore: -------------------------------------------------------------------------------- 1 | ./bin 2 | /bin/ 3 | /obj/ 4 | -------------------------------------------------------------------------------- /.idea/.idea.Youtube-GameOnlineServer/.idea/.name: -------------------------------------------------------------------------------- 1 | Youtube-GameOnlineServer -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ./.idea 2 | ./Youtube-GameOnlineServer/bin 3 | ./Youtube-GameOnlineServer/obj -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "5.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": true 6 | } 7 | } -------------------------------------------------------------------------------- /GameDatabase/RedisCache/RedisDb.cs: -------------------------------------------------------------------------------- 1 | namespace GameDatabase.RedisCache 2 | { 3 | public class RedisDb 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Constants/RoomType.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Rooms.Constants 2 | { 3 | public enum RoomType 4 | { 5 | Lobby, 6 | Battle 7 | } 8 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/IMessageManager.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging 2 | { 3 | public interface IMessageManager 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ### Game Server C# 2 | 3 | Hướng dẫn tạo game server bằng C# .Net5 4 | 5 | Link [Video hướng dẫn](https://www.youtube.com/watch?v=_8upajlC048&list=PLm5N2Ku5IP9eZPS20m8AEpdzYNB-lQ7Dp&ab_channel=CodePh%E1%BB%A7i) 6 | 7 | -------------------------------------------------------------------------------- /.idea/.idea.Youtube-GameOnlineServer/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/Constants/CreatRoomData.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging.Constants 2 | { 3 | public struct CreatRoomData 4 | { 5 | public int Time { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/IMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging 2 | { 3 | public interface IMessage 4 | { 5 | public WsTags Tags { get; set; } 6 | public T Data { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/GameModels/RoomModel.cs: -------------------------------------------------------------------------------- 1 | using Youtube_GameOnlineServer.GameModels.Base; 2 | 3 | namespace Youtube_GameOnlineServer.GameModels 4 | { 5 | public class RoomModel : BaseModel 6 | { 7 | public string RoomName { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /.idea/.idea.Youtube-GameOnlineServer/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Interfaces/IWsGameServer.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Interfaces 2 | { 3 | public interface IWsGameServer 4 | { 5 | void StartServer(); 6 | void StopServer(); 7 | void RestartServer(); 8 | } 9 | } -------------------------------------------------------------------------------- /.idea/.idea.Youtube-GameOnlineServer/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/Constants/LoginData.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging.Constants 2 | { 3 | public struct LoginData 4 | { 5 | public string Username { get; set; } 6 | public string Password { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /.idea/.idea.Youtube-GameOnlineServer/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /contentModel.xml 6 | /modules.xml 7 | /.idea.Youtube-GameOnlineServer.iml 8 | /projectSettingsUpdater.xml 9 | # Datasource local storage ignored files 10 | /dataSources/ 11 | /dataSources.local.xml 12 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/Constants/RegisterData.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging.Constants 2 | { 3 | public struct RegisterData 4 | { 5 | public string Username { get; set; } 6 | public string Password { get; set; } 7 | public string DisplayName { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/WsTags.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging 2 | { 3 | public enum WsTags 4 | { 5 | Invalid, 6 | Login, 7 | Register, 8 | UserInfo, 9 | RoomInfo, 10 | LobbyInfo, 11 | CreateRoom, 12 | QuickPlay 13 | } 14 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/Constants/RoomInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Youtube_GameOnlineServer.Rooms.Constants; 3 | 4 | namespace Youtube_GameOnlineServer.Applications.Messaging.Constants 5 | { 6 | public struct RoomInfo 7 | { 8 | public List Players { get; set; } 9 | public RoomType RoomType { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/Constants/UserInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging.Constants 2 | { 3 | public struct UserInfo 4 | { 5 | public string DisplayName { get; set; } 6 | public string Avatar { get; set; } 7 | public int Level { get; set; } 8 | public long Amount { get; set; } 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/GameModels/Interfaces/IDbHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Youtube_GameOnlineServer.GameModels.Interfaces 4 | { 5 | public interface IDbHandler 6 | { 7 | T Find(string id); 8 | List FindAll(); 9 | T Create(T item); 10 | T Update(string id, T item); 11 | void Remove(string id); 12 | } 13 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Interfaces/IRoomManager.cs: -------------------------------------------------------------------------------- 1 | using Youtube_GameOnlineServer.Rooms.Handlers; 2 | 3 | namespace Youtube_GameOnlineServer.Rooms.Interfaces 4 | { 5 | public interface IRoomManager 6 | { 7 | Lobby Lobby { get; set; } 8 | BaseRoom CreateRoom(int timer); 9 | BaseRoom FindRoom(string id); 10 | bool RemoveRoom(string id); 11 | } 12 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Logging/IGameLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Youtube_GameOnlineServer.Logging 4 | { 5 | public interface IGameLogger 6 | { 7 | void Print(string msg); 8 | void Info(string info); 9 | void Warning(string ms, Exception exception); 10 | void Error(string error, Exception exception); 11 | void Error(string error); 12 | } 13 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Handlers/TikTakToeRoom.cs: -------------------------------------------------------------------------------- 1 | using Youtube_GameOnlineServer.Rooms.Constants; 2 | 3 | namespace Youtube_GameOnlineServer.Rooms.Handlers 4 | { 5 | public class TictacToeRoom : BaseRoom 6 | { 7 | private readonly int _time; 8 | 9 | public TictacToeRoom(int time = 10) : base(RoomType.Battle) 10 | { 11 | _time = time; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Messaging/WsMessage.cs: -------------------------------------------------------------------------------- 1 | namespace Youtube_GameOnlineServer.Applications.Messaging 2 | { 3 | public class WsMessage : IMessage 4 | { 5 | public WsTags Tags { get; set; } 6 | public T Data { get; set; } 7 | 8 | public WsMessage(WsTags tags, T data) 9 | { 10 | Tags = tags; 11 | Data = data; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.dockerignore 2 | **/.env 3 | **/.git 4 | **/.gitignore 5 | **/.project 6 | **/.settings 7 | **/.toolstarget 8 | **/.vs 9 | **/.vscode 10 | **/.idea 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /GameDatabase/GameDatabase.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Handlers/Lobby.cs: -------------------------------------------------------------------------------- 1 | using Youtube_GameOnlineServer.Applications.Interfaces; 2 | using Youtube_GameOnlineServer.Rooms.Constants; 3 | 4 | namespace Youtube_GameOnlineServer.Rooms.Handlers 5 | { 6 | public class Lobby : BaseRoom 7 | { 8 | 9 | public Lobby(RoomType type): base(type) 10 | { 11 | 12 | } 13 | 14 | 15 | public override bool JoinRoom(IPlayer player) 16 | { 17 | return base.JoinRoom(player); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /GameDatabase/Mongodb/Interfaces/IGameDB.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MongoDB.Driver; 3 | 4 | namespace GameDatabase.Mongodb.Interfaces 5 | { 6 | public interface IGameDb where T : class 7 | { 8 | IMongoDatabase GetDatabase(); 9 | IMongoCollection GetCollection(string name); 10 | T Get(FilterDefinition filter); 11 | List GetAll(); 12 | T Create(T item); 13 | void Remove(FilterDefinition filter); 14 | T Update(FilterDefinition filter, UpdateDefinition updater); 15 | } 16 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer.sln.DotSettings.user: -------------------------------------------------------------------------------- 1 | 2 | <AssemblyExplorer> 3 | <Assembly Path="/Users/nguyenquan/.nuget/packages/newtonsoft.json/13.0.1/lib/netstandard2.0/Newtonsoft.Json.dll" /> 4 | </AssemblyExplorer> -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Interfaces/IPlayerManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Collections.Generic; 3 | 4 | namespace Youtube_GameOnlineServer.Applications.Interfaces 5 | { 6 | public interface IPlayerManager 7 | { 8 | ConcurrentDictionary Players { get; set; } 9 | void AddPlayer(IPlayer player); 10 | void RemovePlayer(string id); 11 | void RemovePlayer(IPlayer player); 12 | IPlayer FindPlayer(string id); 13 | IPlayer FindPlayer(IPlayer player); 14 | List GetPlayers(); 15 | } 16 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Interfaces/IPlayer.cs: -------------------------------------------------------------------------------- 1 | using Youtube_GameOnlineServer.Applications.Messaging; 2 | using Youtube_GameOnlineServer.Applications.Messaging.Constants; 3 | 4 | namespace Youtube_GameOnlineServer.Applications.Interfaces 5 | { 6 | public interface IPlayer 7 | { 8 | public string SessionId { get; set; } 9 | public string Name { get; set; } 10 | void SetDisconnect(bool value); 11 | bool SendMessage(string mes); 12 | bool SendMessage(WsMessage message); 13 | void OnDisconnect(); 14 | UserInfo GetUserInfo(); 15 | } 16 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/GameModels/Base/BaseModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MongoDB.Bson; 3 | using MongoDB.Bson.Serialization.Attributes; 4 | 5 | namespace Youtube_GameOnlineServer.GameModels.Base 6 | { 7 | public class BaseModel 8 | { 9 | [BsonId] 10 | [BsonRepresentation(BsonType.ObjectId)] 11 | public string Id { get; set; } 12 | 13 | 14 | 15 | public DateTime CreatedAt { get; set; } 16 | public DateTime UpdateAt { get; set; } 17 | 18 | public BaseModel() 19 | { 20 | CreatedAt = DateTime.Now; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /GameDatabase/Mongodb/Handlers/MongoDb.cs: -------------------------------------------------------------------------------- 1 | using MongoDB.Driver; 2 | 3 | namespace GameDatabase.Mongodb.Handlers 4 | { 5 | public class MongoDb 6 | { 7 | private readonly IMongoClient _client; 8 | private IMongoDatabase Database => _client.GetDatabase("GameOnline"); 9 | public MongoDb() 10 | { 11 | var setting = MongoClientSettings.FromConnectionString("mongodb://localhost:27017/"); 12 | _client = new MongoClient(setting); 13 | } 14 | 15 | public IMongoDatabase GetDatabase() 16 | { 17 | return Database; 18 | } 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /.idea/.idea.Youtube-GameOnlineServer/.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mongo 6 | true 7 | com.dbschema.MongoJdbcDriver 8 | mongodb://localhost:27017/gameonline 9 | $ProjectFileDir$ 10 | 11 | 12 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base 2 | WORKDIR /app 3 | 4 | FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build 5 | WORKDIR /src 6 | COPY ["Youtube-GameOnlineServer/Youtube-GameOnlineServer.csproj", "Youtube-GameOnlineServer/"] 7 | RUN dotnet restore "Youtube-GameOnlineServer/Youtube-GameOnlineServer.csproj" 8 | COPY . . 9 | WORKDIR "/src/Youtube-GameOnlineServer" 10 | RUN dotnet build "Youtube-GameOnlineServer.csproj" -c Release -o /app/build 11 | 12 | FROM build AS publish 13 | RUN dotnet publish "Youtube-GameOnlineServer.csproj" -c Release -o /app/publish 14 | 15 | FROM base AS final 16 | WORKDIR /app 17 | COPY --from=publish /app/publish . 18 | ENTRYPOINT ["dotnet", "Youtube-GameOnlineServer.dll"] 19 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/GameModels/User.cs: -------------------------------------------------------------------------------- 1 | using Youtube_GameOnlineServer.Applications.Handlers; 2 | using Youtube_GameOnlineServer.GameModels.Base; 3 | 4 | namespace Youtube_GameOnlineServer.GameModels 5 | { 6 | public class User : BaseModel 7 | { 8 | public string Username { get; set; } 9 | public string Password { get; set; } 10 | public string DisplayName { get; set; } 11 | public string Avatar { get; set; } 12 | public int Level { get; set; } 13 | public long Amount { get; set; } 14 | 15 | public User(string username, string password, string displayName) 16 | { 17 | Username = username; 18 | DisplayName = displayName; 19 | Password = GameHelper.HashPassword(password); 20 | Avatar = ""; 21 | Level = 1; 22 | Amount = 0; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Interfaces/IBaseRoom.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Youtube_GameOnlineServer.Applications.Interfaces; 3 | using Youtube_GameOnlineServer.Applications.Messaging; 4 | using Youtube_GameOnlineServer.Rooms.Constants; 5 | 6 | namespace Youtube_GameOnlineServer.Rooms.Interfaces 7 | { 8 | public interface IBaseRoom 9 | { 10 | public string Id { get; set; } 11 | public RoomType RoomType { get; set; } 12 | public ConcurrentDictionary Players { get; set; } 13 | 14 | bool JoinRoom(IPlayer player); 15 | bool ExitRoom(IPlayer player); 16 | bool ExitRoom(string id); 17 | IPlayer FindPlayer(string id); 18 | void SendMessage(string mes); 19 | void SendMessage(WsMessage message); 20 | void SendMessage(WsMessage message, string idIgnore); 21 | } 22 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Handlers/GameHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using Newtonsoft.Json; 5 | using System.Security.Cryptography; 6 | namespace Youtube_GameOnlineServer.Applications.Handlers 7 | { 8 | public static class GameHelper 9 | { 10 | public static string ParseString(T data) 11 | { 12 | return JsonConvert.SerializeObject(data); 13 | } 14 | public static string RandomString(int len) 15 | { 16 | var rdn = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid() + $"{DateTime.Now}")); 17 | return rdn[..len]; 18 | } 19 | public static T ParseStruct(string data) 20 | { 21 | return JsonConvert.DeserializeObject(data); 22 | } 23 | 24 | public static string HashPassword(string txt) 25 | { 26 | var crypt = new SHA256Managed(); 27 | var hash = string.Empty; 28 | var bytes = crypt.ComputeHash(Encoding.UTF8.GetBytes(txt)); 29 | return bytes.Aggregate(hash, (current, theByte) => current + theByte.ToString("x2")); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/GameModels/Handlers/RoomHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using GameDatabase.Mongodb.Handlers; 3 | using GameDatabase.Mongodb.Interfaces; 4 | using MongoDB.Driver; 5 | using Youtube_GameOnlineServer.GameModels.Interfaces; 6 | 7 | namespace Youtube_GameOnlineServer.GameModels.Handlers 8 | { 9 | public class RoomHandler : IDbHandler 10 | { 11 | private readonly IGameDb _roomDb; 12 | 13 | public RoomHandler(IMongoDatabase database) 14 | { 15 | _roomDb = new MongoHandler(database); 16 | } 17 | 18 | public RoomModel Find(string id) 19 | { 20 | throw new System.NotImplementedException(); 21 | } 22 | 23 | public List FindAll() 24 | { 25 | throw new System.NotImplementedException(); 26 | } 27 | 28 | public RoomModel Create(RoomModel item) 29 | { 30 | throw new System.NotImplementedException(); 31 | } 32 | 33 | public RoomModel Update(string id, RoomModel item) 34 | { 35 | throw new System.NotImplementedException(); 36 | } 37 | 38 | public void Remove(string id) 39 | { 40 | throw new System.NotImplementedException(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Handlers/RoomManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Linq; 3 | using Youtube_GameOnlineServer.Rooms.Constants; 4 | using Youtube_GameOnlineServer.Rooms.Interfaces; 5 | 6 | namespace Youtube_GameOnlineServer.Rooms.Handlers 7 | { 8 | public class RoomManager : IRoomManager 9 | { 10 | public Lobby Lobby { get; set; } 11 | private ConcurrentDictionary Rooms { get; set; } 12 | 13 | public RoomManager() 14 | { 15 | Rooms = new ConcurrentDictionary(); 16 | Lobby = new Lobby(RoomType.Lobby); 17 | } 18 | 19 | public BaseRoom CreateRoom(int timer) 20 | { 21 | var newRoom = new TictacToeRoom(timer); 22 | Rooms.TryAdd(newRoom.Id, newRoom); 23 | return newRoom; 24 | } 25 | 26 | public BaseRoom FindRoom(string id) 27 | { 28 | return Rooms.FirstOrDefault(r => r.Key == id).Value; 29 | } 30 | 31 | public bool RemoveRoom(string id) 32 | { 33 | var oldRoom = FindRoom(id); 34 | if (oldRoom != null) 35 | { 36 | Rooms.TryRemove(id, out var room); 37 | return room != null; 38 | } 39 | return false; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Youtube-GameOnlineServer", "Youtube-GameOnlineServer\Youtube-GameOnlineServer.csproj", "{45E78C8E-1F89-456B-85FB-C5FE8A68A40B}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameDatabase", "GameDatabase\GameDatabase.csproj", "{538DCF72-2FD7-4315-A718-6509B86B349C}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {45E78C8E-1F89-456B-85FB-C5FE8A68A40B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {45E78C8E-1F89-456B-85FB-C5FE8A68A40B}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {45E78C8E-1F89-456B-85FB-C5FE8A68A40B}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {45E78C8E-1F89-456B-85FB-C5FE8A68A40B}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {538DCF72-2FD7-4315-A718-6509B86B349C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {538DCF72-2FD7-4315-A718-6509B86B349C}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {538DCF72-2FD7-4315-A718-6509B86B349C}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {538DCF72-2FD7-4315-A718-6509B86B349C}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Logging/GameLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Serilog; 3 | using Serilog.Events; 4 | 5 | namespace Youtube_GameOnlineServer.Logging 6 | { 7 | public class GameLogger : IGameLogger 8 | { 9 | private readonly ILogger _logger; 10 | 11 | public GameLogger() 12 | { 13 | _logger = new LoggerConfiguration() 14 | .WriteTo.Console( 15 | outputTemplate: 16 | "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}") 17 | .WriteTo.File("logging/log-.txt", LogEventLevel.Error, rollingInterval: RollingInterval.Day) 18 | .CreateLogger(); 19 | } 20 | 21 | public void Print(string msg) 22 | { 23 | _logger.Information($">>>>> {msg}"); 24 | } 25 | 26 | public void Info(string info) 27 | { 28 | _logger.Information(info); 29 | } 30 | 31 | public void Warning(string ms, Exception exception = null) 32 | { 33 | _logger.Warning(ms, exception); 34 | } 35 | 36 | public void Error(string error, Exception exception) 37 | { 38 | _logger.Error(error, exception); 39 | } 40 | 41 | public void Error(string error) 42 | { 43 | _logger.Error(error); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Youtube-GameOnlineServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | Youtube_GameOnlineServer 7 | Linux 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using GameDatabase.Mongodb.Handlers; 4 | using Youtube_GameOnlineServer.Applications.Handlers; 5 | using Youtube_GameOnlineServer.Applications.Interfaces; 6 | using Youtube_GameOnlineServer.GameModels; 7 | using Youtube_GameOnlineServer.Logging; 8 | using Youtube_GameOnlineServer.Rooms.Handlers; 9 | using Youtube_GameOnlineServer.Rooms.Interfaces; 10 | 11 | namespace Youtube_GameOnlineServer 12 | { 13 | class Program 14 | { 15 | static void Main(string[] args) 16 | { 17 | IGameLogger logger = new GameLogger(); 18 | var mongodb = new MongoDb(); 19 | IPlayerManager playerManager = new PlayersManager(logger); 20 | IRoomManager roomManager = new RoomManager(); 21 | var wsServer = new WsGameServer(IPAddress.Any, 8080, playerManager, logger, mongodb, roomManager); 22 | wsServer.StartServer(); 23 | logger.Print("Game Server started"); 24 | for (;;) 25 | { 26 | var type = Console.ReadLine(); 27 | if (type == "restart") 28 | { 29 | logger.Print("Game Server restarting..."); 30 | wsServer.RestartServer(); 31 | } 32 | 33 | if (type == "shutdown") 34 | { 35 | logger.Print("Game Server stopping..."); 36 | wsServer.StopServer(); 37 | break; 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /GameDatabase/Mongodb/Handlers/MongoHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using GameDatabase.Mongodb.Interfaces; 3 | using MongoDB.Driver; 4 | 5 | namespace GameDatabase.Mongodb.Handlers 6 | { 7 | public class MongoHandler : IGameDb where T : class 8 | { 9 | private readonly IMongoDatabase _database; 10 | private IMongoCollection Collection { get; set; } 11 | public MongoHandler(IMongoDatabase database) 12 | { 13 | _database = database; 14 | this.SetCollection(); 15 | } 16 | 17 | private void SetCollection() 18 | { 19 | switch (typeof(T).Name) 20 | { 21 | case "User": 22 | Collection = _database.GetCollection("Users"); 23 | break; 24 | case "Room": 25 | break; 26 | } 27 | } 28 | 29 | public IMongoDatabase GetDatabase() 30 | { 31 | return _database; 32 | } 33 | 34 | public IMongoCollection GetCollection(string colName) 35 | { 36 | return _database.GetCollection(colName); 37 | } 38 | 39 | public T Get(FilterDefinition filter) 40 | { 41 | return Collection.Find(filter).FirstOrDefault(); 42 | } 43 | 44 | public List GetAll() 45 | { 46 | var filter = Builders.Filter.Empty; 47 | return Collection.Find(filter).ToList(); 48 | } 49 | 50 | public T Create(T item) 51 | { 52 | Collection.InsertOne(item); 53 | return item; 54 | } 55 | 56 | public void Remove(FilterDefinition filter) 57 | { 58 | Collection.DeleteOne(filter); 59 | } 60 | 61 | public T Update(FilterDefinition filter, UpdateDefinition updater) 62 | { 63 | Collection.UpdateOne(filter, updater); 64 | return Get(filter); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Handlers/PlayersManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Youtube_GameOnlineServer.Applications.Interfaces; 6 | using Youtube_GameOnlineServer.Logging; 7 | 8 | namespace Youtube_GameOnlineServer.Applications.Handlers 9 | { 10 | public class PlayersManager : IPlayerManager 11 | { 12 | public ConcurrentDictionary Players { get; set; } 13 | private readonly IGameLogger _logger; 14 | public PlayersManager(IGameLogger logger) 15 | { 16 | _logger = logger; 17 | Players = new ConcurrentDictionary(); 18 | } 19 | public void AddPlayer(IPlayer player) 20 | { 21 | if (FindPlayer(player) == null) 22 | { 23 | Players.TryAdd(player.SessionId, player); 24 | _logger.Info($"List Players {Players.Count}"); 25 | } 26 | 27 | } 28 | 29 | public void RemovePlayer(string id) 30 | { 31 | if (FindPlayer(id) != null) 32 | { 33 | Players.TryRemove(id, out var player); 34 | if (player != null) 35 | { 36 | _logger.Info($"Remove {id} success"); 37 | _logger.Info($"List Players {Players.Count}"); 38 | } 39 | } 40 | } 41 | 42 | public void RemovePlayer(IPlayer player) 43 | { 44 | this.RemovePlayer(player.SessionId); 45 | } 46 | 47 | public IPlayer FindPlayer(string id) 48 | { 49 | return Players.FirstOrDefault(p => p.Key.Equals(id)).Value; 50 | } 51 | 52 | public IPlayer FindPlayer(IPlayer player) 53 | { 54 | return Players.FirstOrDefault(p => p.Value.Equals(player)).Value; 55 | } 56 | 57 | public List GetPlayers() => Players.Values.ToList(); 58 | } 59 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/GameModels/Handlers/UserHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using GameDatabase.Mongodb.Handlers; 4 | using GameDatabase.Mongodb.Interfaces; 5 | using MongoDB.Driver; 6 | using Youtube_GameOnlineServer.GameModels.Interfaces; 7 | 8 | namespace Youtube_GameOnlineServer.GameModels.Handlers 9 | { 10 | public class UserHandler : IDbHandler 11 | { 12 | private readonly IGameDb _userDb; 13 | 14 | public UserHandler(IMongoDatabase database) 15 | { 16 | _userDb = new MongoHandler(database); 17 | } 18 | 19 | public User Find(string id) 20 | { 21 | var filter = Builders.Filter.Eq(i => i.Id, id); 22 | return _userDb.Get(filter); 23 | } 24 | 25 | public List FindAll() 26 | { 27 | return _userDb.GetAll(); 28 | } 29 | 30 | public User FindByUserName(string username) 31 | { 32 | var filter = Builders.Filter.Eq(i => i.Username, username); 33 | return _userDb.Get(filter); 34 | } 35 | 36 | public User Create(User item) 37 | { 38 | var user = _userDb.Create(item); 39 | return user; 40 | } 41 | 42 | public User Update(string id, User item) 43 | { 44 | var filter = Builders.Filter.Eq(i => i.Id, id); 45 | var updater = Builders.Update 46 | .Set(i => i.Password, item.Password) 47 | .Set(i => i.DisplayName, item.DisplayName) 48 | .Set(i => i.Amount, item.Amount) 49 | .Set(i => i.Level, item.Level) 50 | .Set(i => i.Avatar, item.Avatar) 51 | .Set(i => i.UpdateAt, DateTime.Now); 52 | _userDb.Update(filter, updater); 53 | return item; 54 | } 55 | 56 | public void Remove(string id) 57 | { 58 | var filter = Builders.Filter.Eq(i => i.Id, id); 59 | _userDb.Remove(filter); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Logging/TypeNameHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Youtube_GameOnlineServer.Logging 6 | { 7 | public class TypeNameHelper 8 | { 9 | private static readonly Dictionary BuiltInTypeNames = new() 10 | { 11 | { typeof(bool), "bool" }, 12 | { typeof(byte), "byte" }, 13 | { typeof(char), "char" }, 14 | { typeof(decimal), "decimal" }, 15 | { typeof(double), "double" }, 16 | { typeof(float), "float" }, 17 | { typeof(int), "int" }, 18 | { typeof(long), "long" }, 19 | { typeof(object), "object" }, 20 | { typeof(sbyte), "sbyte" }, 21 | { typeof(short), "short" }, 22 | { typeof(string), "string" }, 23 | { typeof(uint), "uint" }, 24 | { typeof(ulong), "ulong" }, 25 | { typeof(ushort), "ushort" } 26 | }; 27 | 28 | public static string GetTypeDisplayName(Type type) 29 | { 30 | if (type.GetTypeInfo().IsGenericType) 31 | { 32 | var fullName = type.GetGenericTypeDefinition().FullName; 33 | 34 | // Nested types (public or private) have a '+' in their full name 35 | var parts = fullName.Split('+'); 36 | 37 | // Handle nested generic types 38 | // Examples: 39 | // ConsoleApp.Program+Foo`1+Bar 40 | // ConsoleApp.Program+Foo`1+Bar`1 41 | for (var i = 0; i < parts.Length; i++) 42 | { 43 | var partName = parts[i]; 44 | 45 | var backTickIndex = partName.IndexOf('`'); 46 | if (backTickIndex >= 0) 47 | { 48 | // Since '.' is typically used to filter log messages in a hierarchy kind of scenario, 49 | // do not include any generic type information as part of the name. 50 | // Example: 51 | // Microsoft.AspNetCore.Mvc -> log level set as Warning 52 | // Microsoft.AspNetCore.Mvc.ModelBinding -> log level set as Verbose 53 | partName = partName.Substring(0, backTickIndex); 54 | } 55 | 56 | parts[i] = partName; 57 | } 58 | 59 | return string.Join(".", parts); 60 | } 61 | else if (BuiltInTypeNames.ContainsKey(type)) 62 | { 63 | return BuiltInTypeNames[type]; 64 | } 65 | else 66 | { 67 | var fullName = type.FullName; 68 | 69 | if (type.IsNested) 70 | { 71 | fullName = fullName.Replace('+', '.'); 72 | } 73 | 74 | return fullName; 75 | } 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Handlers/WsGameServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using GameDatabase.Mongodb.Handlers; 5 | using NetCoreServer; 6 | using Youtube_GameOnlineServer.Applications.Interfaces; 7 | using Youtube_GameOnlineServer.Logging; 8 | using Youtube_GameOnlineServer.Rooms.Interfaces; 9 | 10 | namespace Youtube_GameOnlineServer.Applications.Handlers 11 | { 12 | public class WsGameServer: WsServer, IWsGameServer 13 | { 14 | private readonly int _port; 15 | private readonly IPlayerManager _playerManager; 16 | private readonly IGameLogger _logger; 17 | private readonly MongoDb _mongoDb; 18 | public readonly IRoomManager RoomManager; 19 | public WsGameServer(IPAddress address, int port, IPlayerManager playerManager, IGameLogger logger, MongoDb mongoDb, IRoomManager roomManager) : base(address, port) 20 | { 21 | _port = port; 22 | _playerManager = playerManager; 23 | _logger = logger; 24 | _mongoDb = mongoDb; 25 | RoomManager = roomManager; 26 | } 27 | 28 | protected override TcpSession CreateSession() 29 | { 30 | //todo handle new session 31 | _logger.Info("New Session connected"); 32 | var player = new Player(this, _mongoDb.GetDatabase()); 33 | _playerManager.AddPlayer(player); 34 | return player; 35 | } 36 | 37 | protected override void OnDisconnected(TcpSession session) 38 | { 39 | _logger.Info("Session disconnected"); 40 | var player = _playerManager.FindPlayer(session.Id.ToString()); 41 | if (player != null) 42 | { 43 | //player.SetDisconnect(true); 44 | _playerManager.RemovePlayer(player); 45 | //todo mark player disconnected 46 | } 47 | base.OnDisconnected(session); 48 | } 49 | 50 | public void SendAll(string mes) 51 | { 52 | this.MulticastText(mes); 53 | } 54 | 55 | public void StartServer() 56 | { 57 | //todo logic before start server 58 | if (this.Start()) 59 | { 60 | _logger.Print($"Server Ws started at {_port}"); 61 | return; 62 | } 63 | 64 | } 65 | 66 | protected override void OnError(SocketError error) 67 | { 68 | _logger.Error($"Server Ws error"); 69 | base.OnError(error); 70 | } 71 | 72 | public void StopServer() 73 | { 74 | //todo logic before stop server 75 | this.Stop(); 76 | _logger.Print("Server Ws stopped"); 77 | } 78 | 79 | public void RestartServer() 80 | { 81 | //todo logic before stop server 82 | if (this.Restart()) 83 | { 84 | _logger.Print("Server Ws restarted"); 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Rooms/Handlers/BaseRoom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Linq; 4 | using Youtube_GameOnlineServer.Applications.Handlers; 5 | using Youtube_GameOnlineServer.Applications.Interfaces; 6 | using Youtube_GameOnlineServer.Applications.Messaging; 7 | using Youtube_GameOnlineServer.Applications.Messaging.Constants; 8 | using Youtube_GameOnlineServer.Rooms.Constants; 9 | using Youtube_GameOnlineServer.Rooms.Interfaces; 10 | 11 | namespace Youtube_GameOnlineServer.Rooms.Handlers 12 | { 13 | public class BaseRoom : IBaseRoom 14 | { 15 | public string Id { get; set; } 16 | public RoomType RoomType { get; set; } 17 | public ConcurrentDictionary Players { get; set; } 18 | 19 | public BaseRoom(RoomType type) 20 | { 21 | RoomType = type; 22 | Id = GameHelper.RandomString(10); 23 | Players = new ConcurrentDictionary(); 24 | } 25 | 26 | public virtual bool JoinRoom(IPlayer player) 27 | { 28 | if (FindPlayer(player.SessionId) == null) 29 | { 30 | if (Players.TryAdd(player.SessionId, player)) 31 | { 32 | this.RoomInfo(); 33 | return true; 34 | } 35 | } 36 | 37 | return false; 38 | } 39 | 40 | private void RoomInfo() 41 | { 42 | var lobby = new RoomInfo 43 | { 44 | RoomType = RoomType, 45 | Players = Players.Values.Select(p => p.GetUserInfo()).ToList() 46 | }; 47 | var mess = new WsMessage(WsTags.RoomInfo, lobby); 48 | this.SendMessage(mess); 49 | } 50 | 51 | public virtual bool ExitRoom(IPlayer player) 52 | { 53 | return this.ExitRoom(player.SessionId); 54 | } 55 | 56 | public virtual bool ExitRoom(string id) 57 | { 58 | var player = FindPlayer(id); 59 | if (player != null) 60 | { 61 | Players.TryRemove(player.SessionId, out player); 62 | this.RoomInfo(); 63 | return true; 64 | } 65 | 66 | return false; 67 | } 68 | 69 | public virtual IPlayer FindPlayer(string id) 70 | { 71 | return Players.FirstOrDefault(p => p.Key.Equals(id)).Value; 72 | } 73 | 74 | public void SendMessage(string mes) 75 | { 76 | lock (Players) 77 | { 78 | foreach (var player in Players.Values) 79 | { 80 | player.SendMessage(mes); 81 | } 82 | } 83 | } 84 | 85 | public void SendMessage(WsMessage message) 86 | { 87 | lock (Players) 88 | { 89 | foreach (var player in Players.Values) 90 | { 91 | player.SendMessage(message); 92 | } 93 | } 94 | } 95 | 96 | public void SendMessage(WsMessage message, string idIgnore) 97 | { 98 | lock (Players) 99 | { 100 | foreach (var player in Players.Values.Where(p => p.SessionId != idIgnore)) 101 | { 102 | player.SendMessage(message); 103 | } 104 | } 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /Youtube-GameOnlineServer/Applications/Handlers/Player.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using GameDatabase.Mongodb.Handlers; 4 | using GameDatabase.Mongodb.Interfaces; 5 | using MongoDB.Driver; 6 | using NetCoreServer; 7 | using Youtube_GameOnlineServer.Applications.Interfaces; 8 | using Youtube_GameOnlineServer.Applications.Messaging; 9 | using Youtube_GameOnlineServer.Applications.Messaging.Constants; 10 | using Youtube_GameOnlineServer.GameModels; 11 | using Youtube_GameOnlineServer.GameModels.Handlers; 12 | using Youtube_GameOnlineServer.Logging; 13 | 14 | namespace Youtube_GameOnlineServer.Applications.Handlers 15 | { 16 | public class Player : WsSession, IPlayer 17 | { 18 | public string SessionId { get; set; } 19 | public string Name { get; set; } 20 | private bool IsDisconnected { get; set; } 21 | private readonly IGameLogger _logger; 22 | private UserHandler UsersDb { get; set; } 23 | private User UserInfo { get; set; } 24 | 25 | public Player(WsServer server, IMongoDatabase database) : base(server) 26 | { 27 | SessionId = this.Id.ToString(); 28 | IsDisconnected = false; 29 | _logger = new GameLogger(); 30 | UsersDb = new UserHandler(database); 31 | } 32 | 33 | public override void OnWsConnected(HttpRequest request) 34 | { 35 | //todo login on player connected 36 | var url = request.Url; 37 | _logger.Info("Player connected"); 38 | IsDisconnected = false; 39 | } 40 | 41 | public override void OnWsDisconnected() 42 | { 43 | OnDisconnect(); 44 | base.OnWsDisconnected(); 45 | } 46 | 47 | 48 | public override void OnWsReceived(byte[] buffer, long offset, long size) 49 | { 50 | var mess = Encoding.UTF8.GetString(buffer, (int) offset, (int) size); 51 | try 52 | { 53 | var wsMess = GameHelper.ParseStruct>(mess); 54 | switch (wsMess.Tags) 55 | { 56 | case WsTags.Invalid: 57 | break; 58 | case WsTags.Login: 59 | var loginData = GameHelper.ParseStruct(wsMess.Data.ToString()); 60 | UserInfo = UsersDb.FindByUserName(loginData.Username); 61 | if (UserInfo != null) 62 | { 63 | var hashPass = GameHelper.HashPassword(loginData.Password); 64 | if (hashPass == UserInfo.Password) 65 | { 66 | //todo move user to lobby 67 | var messInfo = new WsMessage(WsTags.UserInfo, this.GetUserInfo()); 68 | this.SendMessage(messInfo); 69 | this.PlayerJoinLobby(); 70 | return; 71 | } 72 | } 73 | 74 | var invalidMess = new WsMessage(WsTags.Invalid, "Username Or Password is Invalid"); 75 | this.SendMessage(GameHelper.ParseString(invalidMess)); 76 | break; 77 | case WsTags.Register: 78 | var regData = GameHelper.ParseStruct(wsMess.Data.ToString()); 79 | if (UserInfo != null) 80 | { 81 | invalidMess = new WsMessage(WsTags.Invalid, "You are Loginned"); 82 | this.SendMessage(GameHelper.ParseString(invalidMess)); 83 | return; 84 | } 85 | var check = UsersDb.FindByUserName(regData.Username); 86 | if (check != null) 87 | { 88 | invalidMess = new WsMessage(WsTags.Invalid, "Username exits"); 89 | this.SendMessage(GameHelper.ParseString(invalidMess)); 90 | return; 91 | } 92 | 93 | 94 | 95 | var newUser = new User(regData.Username, regData.Password, regData.DisplayName); 96 | UserInfo = UsersDb.Create(newUser); 97 | if (UserInfo != null) 98 | { 99 | //todo move user to lobby 100 | this.PlayerJoinLobby(); 101 | } 102 | 103 | break; 104 | case WsTags.RoomInfo: 105 | break; 106 | case WsTags.UserInfo: 107 | break; 108 | case WsTags.CreateRoom: 109 | var createRoom = GameHelper.ParseStruct(wsMess.Data.ToString()); 110 | this.OnUserCreateRoom(createRoom); 111 | break; 112 | case WsTags.QuickPlay: 113 | break; 114 | default: 115 | break; 116 | //throw new ArgumentOutOfRangeException(); 117 | } 118 | } 119 | catch (Exception e) 120 | { 121 | _logger.Error("OnWsReceived error", e); 122 | //todo send invalid message 123 | } 124 | //((WsGameServer) Server).SendAll($"{this.SessionId} send message {mess}"); 125 | } 126 | 127 | private void OnUserCreateRoom(CreatRoomData data) 128 | { 129 | var room = ((WsGameServer) Server).RoomManager.CreateRoom(data.Time); 130 | if (room != null && room.JoinRoom(this)) 131 | { 132 | var lobby = ((WsGameServer) Server).RoomManager.Lobby; 133 | lobby.ExitRoom(this); 134 | } 135 | } 136 | private void PlayerJoinLobby() 137 | { 138 | var lobby = ((WsGameServer) Server).RoomManager.Lobby; 139 | lobby.JoinRoom(this); 140 | //todo logic join lobby 141 | } 142 | 143 | public void SetDisconnect(bool value) 144 | { 145 | this.IsDisconnected = value; 146 | } 147 | 148 | public bool SendMessage(string mes) 149 | { 150 | return this.SendTextAsync(mes); 151 | } 152 | 153 | public bool SendMessage(WsMessage message) 154 | { 155 | var mes = GameHelper.ParseString(message); 156 | return this.SendMessage(mes); 157 | } 158 | 159 | public void OnDisconnect() 160 | { 161 | //todo logic handle player disconnect 162 | var lobby = ((WsGameServer) Server).RoomManager.Lobby; 163 | lobby.ExitRoom(this); 164 | _logger.Warning("Player disconnected", null); 165 | //((WsGameServer) Server).PlayerManager.RemovePlayer(this); 166 | } 167 | 168 | public UserInfo GetUserInfo() 169 | { 170 | if (UserInfo != null) 171 | { 172 | return new UserInfo 173 | { 174 | DisplayName = UserInfo.DisplayName, 175 | Amount = UserInfo.Amount, 176 | Avatar = UserInfo.Avatar, 177 | Level = UserInfo.Level, 178 | }; 179 | } 180 | 181 | return new UserInfo(); 182 | } 183 | } 184 | } --------------------------------------------------------------------------------