Campofinale/Campofinale/Server.cs
2025-03-07 20:49:49 +01:00

197 lines
6.4 KiB
C#

using BeyondTools.VFS.Crypto;
using Campofinale.Commands;
using Campofinale.Database;
using Campofinale.Game;
using Campofinale.Http;
using Campofinale.Network;
using Campofinale.Protocol;
using Campofinale.Resource;
using Google.Protobuf;
using Newtonsoft.Json;
using Pastel;
using SQLite;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static Campofinale.Http.Dispatch;
namespace Campofinale
{
public static class DateTimeExtensions
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long ToUnixTimestampMilliseconds(this DateTime dateTime)
{
return (long)(dateTime - UnixEpoch).TotalMilliseconds;
}
}
public class Server
{
public class HandlerAttribute : Attribute
{
public CsMsgId CmdId { get; set; }
public HandlerAttribute(CsMsgId cmdID)
{
this.CmdId = cmdID;
}
public delegate void HandlerDelegate(Player client, int cmdId, Network.Packet packet);
}
public class CommandAttribute : Attribute
{
public string command;
public string desc;
public bool requiredTarget;
public CommandAttribute(string cmdName, string desc = "No description", bool requireTarget=false)
{
this.command = cmdName;
this.desc = desc;
this.requiredTarget = requireTarget;
}
public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target);
}
public static List<Player> clients = new List<Player>();
public static string ServerVersion = "1.1.2-dev";
public static bool Initialized = false;
public static bool showLogs = true;
public static Dispatch dispatch;
public static ResourceManager resourceManager;
public static ConfigFile config;
public static List<CsMsgId> csMessageToHide = new() { CsMsgId.CsMoveObjectMove, CsMsgId.CsBattleOp,CsMsgId.CsPing };
public static List<ScMsgId> scMessageToHide = new() { ScMsgId.ScMoveObjectMove, ScMsgId.ScPing };
public static ResourceManager GetResources()
{
return resourceManager;
}
public void Start(bool hideLogs = false, ConfigFile config = null)
{
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
NotifyManager.AddReqGroupHandler(type);
CommandManager.AddReqGroupHandler(type);
}
NotifyManager.Init();
CommandManager.Init();
}
Logger.Initialize();
Logger.Print($"Starting server version {ServerVersion} with supported client version {GameConstants.GAME_VERSION}");
showLogs = !hideLogs;
Logger.Print($"Logs are {(showLogs ? "enabled" : "disabled")}");
Server.config = config;
DatabaseManager.Init();
ResourceManager.Init();
new Thread(new ThreadStart(DispatchServer)).Start();
IPAddress ipAddress = IPAddress.Parse(Server.config.gameServer.bindAddress);
int port = Server.config.gameServer.bindPort;
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
new Thread(new ThreadStart(CmdListener)).Start();
new Thread(new ThreadStart(Update)).Start();
try
{
serverSocket.Bind(new IPEndPoint(ipAddress, port));
serverSocket.Listen(int.MaxValue);
Logger.Print($"Server listening on {ipAddress}:{port}");
Initialized = true;
while (true)
{
Socket clientSocket = serverSocket.Accept();
if (clientSocket.Connected)
{
Player client = new Player(clientSocket);
clients.Add(client);
client.receivorThread.Start();
Logger.Print("Connected new client: " + clients.Count());
}
}
}
catch (Exception ex)
{
Logger.PrintError($" {ex.Message}");
}
finally
{
serverSocket.Close();
Logger.Print("Server stopped.");
}
}
public void Update()
{
while (true)
{
try
{
clients.ForEach(client => { if (client != null) client.Update(); });
Thread.Sleep(1000);
}
catch (Exception ex)
{
}
}
}
public void CmdListener()
{
while (true)
{
try
{
string cmd = Console.ReadLine()!;
string[] split = cmd.Split(" ");
string[] args = cmd.Split(" ").Skip(1).ToArray();
string command = split[0].ToLower();
CommandManager.Notify(null,command, args,clients.Find(c=>c.accountId==CommandManager.targetId));
}
catch (Exception ex)
{
Logger.PrintError(ex.Message);
}
}
}
public void DispatchServer()
{
dispatch = new Dispatch();
dispatch.Start();
}
public static CsMsgId[] hideLog = [];
public static string ColoredText(string text, string color)
{
return text.Pastel(color);
}
public static void Shutdown()
{
foreach (Player player in clients)
{
if(player.Initialized)
player.Save();
player.Kick(CODE.ErrServerClosed);
}
}
}
}