forked from SoDOff-Project/sodoff
120 lines
3.7 KiB
C#
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.");
|
|
}
|
|
}
|