197 lines
6.4 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|