jumpstart-games-reduxed/src/Services/MMOClientService.cs

120 lines
3.7 KiB
C#

using System;
using Microsoft.Extensions.Options;
using Sfs2X;
using Sfs2X.Core;
using Sfs2X.Entities;
using Sfs2X.Entities.Data;
using Sfs2X.Entities.Variables;
using Sfs2X.Requests;
using Sfs2X.Util;
using sodoff.Configuration;
namespace sodoff.Services;
public class MMOClientService : IHostedService
{
private readonly IOptions<ApiServerConfig> Config;
private ConfigData SFSConfig;
public SmartFox SFSClient { get; private set; }
public bool IsLoggedIn { get; private set; }
public User? CurrentUser { get; private set; }
public MMOClientService(IOptions<ApiServerConfig> config)
{
Config = config;
// set SFSConfig
SFSConfig = new ConfigData();
SFSConfig.Host = Config.Value.MMOAdress;
SFSConfig.Port = Config.Value.MMOPort;
SFSConfig.Zone = "JumpStart";
// set SFSClient
SFSClient = new SmartFox();
SFSClient.ThreadSafeMode = false; // this is set to true by default which requires Unity's thread processing stuff
}
public Task StartAsync(CancellationToken cancellationToken)
{
// connect and login to mmo server using SFSConfig
Console.WriteLine("Starting Connection To MMO Server...");
SFSClient.Connect(SFSConfig);
SFSClient.AddEventListener(SFSEvent.CONNECTION, OnConnectionEstablished);
SFSClient.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
SFSClient.AddEventListener(SFSEvent.LOGIN, OnLogin);
// return completed task (SmartFox seems to be completely synchronous)
return Task.CompletedTask;
}
public Task SetRoomVarForRoom(int roomId, RoomVariable var)
{
if (IsLoggedIn)
{
Room room = SFSClient.GetRoomById(roomId);
if (room != null) room.SetVariable(var);
else return Task.CompletedTask;
}
else throw new InvalidOperationException("MMO Client Was Not Ready");
return Task.CompletedTask;
}
public Task SendCommandToUser(string userId, string cmd, string[] parameters)
{
// SFSClient doesn't seem to have a method to send commands to specific users, so we'll make a custom extension endpoint that will handle it
ISFSObject obj = SFSObject.NewInstance();
obj.PutUtfString("UID", userId);
obj.PutUtfString("CMD", cmd);
obj.PutUtfStringArray("ARR", parameters);
SFSClient.Send(new ExtensionRequest("SUE", obj));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Stopping Connection To MMO Server...");
if(SFSClient.IsConnected)
{
if(IsLoggedIn) SFSClient.Send(new LogoutRequest());
SFSClient.Disconnect();
}
return Task.CompletedTask;
}
private void OnConnectionEstablished(BaseEvent evt)
{
bool success = (bool)evt.Params["success"];
if (success)
{
Console.WriteLine("Connection Established. Sending Login Request...");
SFSClient.Send(new LoginRequest("API"));
}
}
private void OnConnectionLost(BaseEvent evt)
{
Console.WriteLine($"Connection To The MMO Server Was Lost. Reason - {(string)evt.Params["reason"]}");
Console.WriteLine("MMO Service Currently Not Ready.\nThis Required A Full API Restart For Realtime Communication To Be Reestablished.");
}
private void OnLogin(BaseEvent evt)
{
CurrentUser = (User)evt.Params["user"];
IsLoggedIn = CurrentUser != null;
Console.WriteLine($"Logged In? - {IsLoggedIn}");
if (IsLoggedIn) Console.WriteLine("MMO Service Ready.");
else Console.WriteLine("MMO Service Not Ready.");
}
}