private static async Task Main(string[] args) { if (args.Length != 2) { throw new ArgumentException("Expected 2 argument."); } if (!Guid.TryParse(args[0], out var id)) { throw new ArgumentException($"{args[0]} is not a valid GUID"); } ServerSpecification specification; await using (var ctx = new NovaContext()) { specification = await ctx.Specifications.FirstOrDefaultAsync(c => c.Id == id); if (specification == default) { throw new ArgumentException($"{args[0]} is not a valid server specification ID"); } } var server = new Server(specification.Id); await server.ConfigureAsync(args[1]); Logger.Information($"Starting server {server.Port}..."); await server.Start(); }
public async Task ConfigureAsync(string configFile) { var serializer = new XmlSerializer(typeof(Configuration)); await using var fs = File.OpenRead(configFile); Logger.Config = Config = (Configuration)serializer.Deserialize(fs); if (!File.Exists(configFile)) { throw new ArgumentException($"{configFile} config file does not exist."); } if (!string.IsNullOrWhiteSpace(Config.ResourcesConfiguration?.GameResourceFolder)) { Resources = new LocalResources(Config); } ServerSpecification specification; await using (var ctx = new NovaContext()) { specification = await ctx.Specifications.FirstAsync(s => s.Id == Id); } Port = specification.Port; _server = new RakNetServer(Port, "3.25 ND1"); }
private static async Task AnswerRequest(WorldServerRequest request, ushort instanceId) { await using var ctx = new NovaContext(); var req = await ctx.WorldServerRequests.FirstAsync(r => r.Id == request.Id); req.SpecificationId = await StartWorld(request.ZoneId, default, instanceId);
private static async Task Main(string[] args) { await OpenConfig(); await using (var ctx = new NovaContext()) { await ctx.EnsureUpdatedAsync(); foreach (var specification in ctx.Specifications) { ctx.Specifications.Remove(specification); } foreach (var request in ctx.WorldServerRequests) { ctx.WorldServerRequests.Remove(request); } await ctx.SaveChangesAsync(); } await StartAuthentication(); await StartCharacter(); Console.CancelKeyPress += ShutdownProcesses; AppDomain.CurrentDomain.ProcessExit += ShutdownProcesses; await HandleRequests(); }
public async Task HandleMinifigureListRequest(MinifigureListRequestPacket packet, Connection connection) { await using var ctx = new NovaContext(); if (connection.Username == default) { // Not yet validated return; } var account = await ctx.Accounts .Include(a => a.Characters) .FirstOrDefaultAsync(a => a.Username == connection.Username); if (account == default) { connection.Send(new MinifigureListResponsePacket()); return; } account.Characters.Sort((u2, u1) => DateTimeOffset.Compare(DateTimeOffset.FromUnixTimeSeconds(u1.LastActivity), DateTimeOffset.FromUnixTimeSeconds(u2.LastActivity))); connection.Send(new MinifigureListResponsePacket { Characters = account.Characters }); }
private static async Task HandleRequest(WorldServerRequest request) { await using var ctx = new NovaContext(); if (request.State == WorldServerRequestState.Unanswered) { // // Search for available server // foreach (var worldServer in WorldServers.Where(w => w.ZoneId == request.ZoneId)) { var specification = await ctx.Specifications.FirstAsync(s => s.Id == worldServer.Id); if (specification.ActiveUserCount >= specification.MaxUserCount) { continue; } var req = await ctx.WorldServerRequests.FirstAsync(r => r.Id == request.Id); req.SpecificationId = specification.Id; req.State = WorldServerRequestState.Complete; await ctx.SaveChangesAsync(); return; } // // Start new server // ushort instanceId = 0; for (var i = 0; i < ushort.MaxValue; i++) { if (WorldServers.Any(w => w.InstanceId == instanceId)) { instanceId++; continue; } await AnswerRequest(request, instanceId); break; } } }
private static async Task HandleRequests() { while (true) { await Task.Delay(100); await using var ctx = new NovaContext(); // // Cleanup // for (var index = 0; index < WorldServers.Count; index++) { var worldServer = WorldServers[index]; if (worldServer.Process.HasExited) { WorldServers.RemoveAt(index); } else { var specifications = await ctx.Specifications.FirstAsync(w => w.Id == worldServer.Id); if (specifications.ActiveUserCount != default) { worldServer.EmptyTime = default; continue; } worldServer.EmptyTime++; if (worldServer.EmptyTime != 10000) { continue; } // Evil, but works worldServer.Process.Kill(); WorldServers.RemoveAt(index); } } foreach (var request in ctx.WorldServerRequests) { await HandleRequest(request); } } }
public async Task HandleMinifigureCreation(CreateMinifigurePacket packet, Connection connection) { Logger.Information($"Creating character: {packet.MinifigureName}"); await using var ctx = new NovaContext(); var account = await ctx.Accounts .Include(a => a.Characters) .FirstOrDefaultAsync(a => a.Username == connection.Username); if (account == default) { connection.Send(new MinifigureListResponsePacket()); return; } if (await ctx.Characters.AnyAsync(c => c.Name == packet.MinifigureName)) { connection.Send(new CreateMinifigureResponsePacket { ResponseCode = 3 }); return; } account.Characters.Add(new Character { Name = packet.MinifigureName, ShirtColor = packet.ShirtColor, ShirtStyle = packet.ShirtStyle, PantsColor = packet.PantsColor, Eyebrows = packet.Eyebrows, Eyes = packet.Eyes, Rh = packet.Rh, Lh = packet.Lh, HairColor = packet.HairColor, HairStyle = packet.HairStyle, Mouth = packet.Mouth, ObjectId = IdUtilities.GenerateObjectId() }); await ctx.SaveChangesAsync(); connection.Send(new CreateMinifigureResponsePacket { ResponseCode = 0 }); await HandleMinifigureListRequest(default, connection);
public static async Task RequestWorldServerAsync(ZoneId zoneId, Action <int> callback) { var id = Guid.NewGuid(); await using (var ctx = new NovaContext()) { await ctx.WorldServerRequests.AddAsync(new WorldServerRequest { Id = id, ZoneId = zoneId }); await ctx.SaveChangesAsync(); } var _ = Task.Run(async() => { var timeout = 1000; while (timeout != default) { await using var ctx = new NovaContext(); var request = await ctx.WorldServerRequests.FirstAsync(r => r.Id == id); if (request.State != WorldServerRequestState.Complete) { timeout--; await Task.Delay(100).ConfigureAwait(false); continue; } Logger.Information($"Request completed {id} {request.SpecificationId}"); ctx.WorldServerRequests.Remove(request); await ctx.SaveChangesAsync(); var specification = await ctx.Specifications.FirstAsync(s => s.Id == request.SpecificationId); callback(specification.Port); return; } Logger.Error($"Request {id} timed out"); }); }
public async Task HandleClientLogin(ClientLoginInfoPacket packet, Connection connection) { await using var ctx = new NovaContext(); var account = await ctx.Accounts.FirstOrDefaultAsync(a => a.Username == packet.Username); if (account == default) { await ctx.Accounts.AddAsync(new Account { Username = packet.Username, Hash = BCrypt.Net.BCrypt.EnhancedHashPassword(packet.Password) }); await ctx.SaveChangesAsync(); Logger.Information($"Created new account: {packet.Username}"); connection.Send(new ClientLoginReplyPacket { ResultCode = LoginResultCode.Success, NewServerIp = "127.0.0.1", NewServerPort = 2002 }); return; } if (!BCrypt.Net.BCrypt.EnhancedVerify(packet.Password, account.Hash)) { connection.Send(new ClientLoginReplyPacket { ResultCode = LoginResultCode.IncorrectInfo, NewServerIp = "127.0.0.1", NewServerPort = 1001 }); Logger.Information($"{packet.Username} failed to login"); return; } connection.Send(new ClientLoginReplyPacket { ResultCode = LoginResultCode.Success, NewServerIp = "127.0.0.1", NewServerPort = 2002 }); }
public Visma(int company) { this.company = company; this._context = GetContext(); vismaConnection = GetSqlConnection(); otrivitTA = new DataSetTableAdapters.OTRIVITableAdapter(); otrivitTA.Connection = vismaConnection; varastoTA = new DataSetTableAdapters.VARASTOTableAdapter(); varastoTA.Connection = vismaConnection; hinnastoTA = new DataSetTableAdapters.HINNASTOTableAdapter(); hinnastoTA.Connection = vismaConnection; }
/// <summary> /// Get Context object to Nova Visma instance. /// </summary> /// <returns></returns> public NovaContext GetContext() { string vismaServer = ConfigurationSettings.AppSettings["Visma.Server"]; string vismaUsername = ConfigurationSettings.AppSettings["Visma.Server"]; string vismaPassword = ConfigurationSettings.AppSettings["Visma.Password"]; int vismaCompany = this.company; NovaContext context; if (string.IsNullOrEmpty(vismaUsername) || string.IsNullOrEmpty(vismaPassword)) { context = new NovaContext(vismaServer, vismaCompany); } else { context = new NovaContext(vismaServer, vismaUsername, vismaPassword, vismaCompany); } Nova.Configuration.Settings.SetDataConnectionString(context.CompanyConnectionString); return(context); }
public async Task HandleClientLoaded(ClientLoadCompletePacket packet, Connection connection) { await using var ctx = new NovaContext(); var account = await ctx.Accounts .Include(a => a.Characters) .FirstOrDefaultAsync(a => a.Username == connection.Username); if (account == default) { connection.Send(new DisconnectNotifyPacket { ErrorCode = 1 }); return; } var character = account.Characters.FirstOrDefault(c => c.ObjectId == account.SelectedCharacter); if (character == default) { connection.Send(new DisconnectNotifyPacket { ErrorCode = 1 }); return; } SendCharacterData(connection, character); connection.Send(new CharacterEndMarkerPacket { ServerOnline = true }); }
public async Task Start() { await using var ctx = new NovaContext(); await ctx.EnsureUpdatedAsync(); _server.Start(); RegisterAssembly(typeof(Server).Assembly); RegisterAssembly(Assembly.GetEntryAssembly()); _server.NewConnection += point => { var connection = new Connection(point, _server); Connections.Add(connection); OnConnection?.Invoke(connection); }; _server.Disconnection += point => { var connection = Connections.FirstOrDefault(c => c.EndPoint.Equals(point)); if (connection == default) { return; } Connections.Remove(connection); OnDisconnect?.Invoke(connection); }; _server.PacketReceived += (point, bytes) => { var connection = Connections.FirstOrDefault(c => c.EndPoint.Equals(point)); if (connection == default) { Logger.Warning($"{point} is not connected but we still got data from them!"); return; } using var stream = new MemoryStream(bytes); using var reader = new BitReader(stream); var id = (MessageIdentifiers)reader.Read <byte>(); if (id != MessageIdentifiers.UserPacketEnum) { Logger.Error($"Invalid packet: {id}"); return; } HandlePacket(reader, connection); reader.BaseStream.Position = 0; OnPacket?.Invoke(connection, reader); }; var request = ctx.WorldServerRequests.FirstOrDefault(w => w.SpecificationId == Id); if (request != default) { Logger.Information($"Request found for {Id}"); request.State = WorldServerRequestState.Complete; await ctx.SaveChangesAsync(); } await ctx.DisposeAsync(); while (true) { var command = Console.ReadLine(); } }
public async Task HandleWorldLogin(WorldLoginPacket packet, Connection connection) { await using var ctx = new NovaContext(); var account = await ctx.Accounts .Include(a => a.Characters) .FirstOrDefaultAsync(a => a.Username == connection.Username); if (account == default) { connection.Send(new DisconnectNotifyPacket { ErrorCode = 1 }); return; } var character = account.Characters.FirstOrDefault(c => c.ObjectId == packet.MinifigureId); if (character == default) { connection.Send(new DisconnectNotifyPacket { ErrorCode = 1 }); return; } if (character.LastZoneId == 0) { character.LastZoneId = ZoneId.VentureExplorer; } account.SelectedCharacter = character.ObjectId; character.LastActivity = DateTimeOffset.Now.ToUnixTimeSeconds(); await ctx.SaveChangesAsync(); if (Server.Port == 2002) { await Server.RequestWorldServerAsync(character.LastZoneId, port => { connection.Send(new TransferToWorldPacket { Ip = "127.0.0.1", Port = (ushort)port }); }); return; } connection.Send(new LoadStaticZonePacket { ZoneId = (ushort)character.LastZoneId, ZoneRevision = 5864, Instance = 0, Clone = 1 }); }
public async Task HandleClientValidation(ValidateClientPacket packet, Connection connection) { await using var ctx = new NovaContext(); var account = await ctx.Accounts .Include(a => a.Characters) .FirstOrDefaultAsync(a => a.Username == packet.Username); if (account == default) { connection.Send(new DisconnectNotifyPacket { ErrorCode = 1 }); return; } Logger.Debug($"Client validating as: {packet.Username}"); connection.Username = packet.Username; if (Server.Port == 2002) { if (!account.Characters.Any()) { return; } account.Characters.Sort((u2, u1) => DateTimeOffset.Compare(DateTimeOffset.FromUnixTimeSeconds(u1.LastActivity), DateTimeOffset.FromUnixTimeSeconds(u2.LastActivity))); connection.Send(new MinifigureListResponsePacket { Characters = account.Characters.ToList() }); return; } var character = account.Characters.FirstOrDefault(c => c.ObjectId == account.SelectedCharacter); if (character == null) { connection.Send(new DisconnectNotifyPacket { ErrorCode = 1 }); return; } connection.Send(new LoadStaticZonePacket { ZoneId = (ushort)character.LastZoneId, ZoneRevision = 5864, Instance = 0, Clone = 1 }); Logger.Information($"Sending {character.Name} to {character.LastZoneId}"); }