forked from SoDOff-Project/sodoff
implement realtime communication with mmo server
-also added messages for anyone on wojs or earlier for ribbons -mmo communication occurs in the ``MessagingService`` and ``BuddyService`` -for now this requires a DLL from the game client as we should not distribute the SmartFox client openly here due to it being closed sourced
This commit is contained in:
parent
0a97ff8d42
commit
6fab853d5f
3
.gitignore
vendored
3
.gitignore
vendored
@ -13,4 +13,5 @@ src/Properties
|
||||
__pycache__/
|
||||
sodoff.db
|
||||
sodoff.db-shm
|
||||
sodoff.db-wal
|
||||
sodoff.db-wal
|
||||
src/Dlls/SmartFox2X.dll
|
@ -1754,6 +1754,7 @@ public class ContentController : Controller {
|
||||
{
|
||||
existingScene.XmlData = contentXml;
|
||||
ctx.SaveChanges();
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
else
|
||||
@ -1764,7 +1765,8 @@ public class ContentController : Controller {
|
||||
XmlData = contentXml
|
||||
};
|
||||
viking.SceneData.Add(sceneData);
|
||||
ctx.SaveChanges();
|
||||
ctx.SaveChanges();
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ builder.Services.AddSingleton<ItemService>();
|
||||
builder.Services.AddSingleton<StoreService>();
|
||||
builder.Services.AddSingleton<DisplayNamesService>();
|
||||
builder.Services.AddSingleton<MMOConfigService>();
|
||||
builder.Services.AddSingleton<MMOClientService>();
|
||||
builder.Services.AddSingleton<WorldIdService>();
|
||||
|
||||
builder.Services.AddScoped<KeyValueService>();
|
||||
@ -44,6 +45,8 @@ builder.Services.AddScoped<ModerationService>();
|
||||
builder.Services.AddScoped<MessagingService>();
|
||||
builder.Services.AddScoped<BuddyService>();
|
||||
|
||||
builder.Services.AddHostedService<MMOClientService>(provider => provider.GetService<MMOClientService>());
|
||||
|
||||
bool assetServer = builder.Configuration.GetSection("AssetServer").GetValue<bool>("Enabled");
|
||||
string assetIP = builder.Configuration.GetSection("AssetServer").GetValue<string>("ListenIP");
|
||||
int assetPort = builder.Configuration.GetSection("AssetServer").GetValue<int>("Port");
|
||||
|
@ -12,7 +12,8 @@ namespace sodoff.Services {
|
||||
private MessagingService messagingService;
|
||||
public readonly DBContext ctx;
|
||||
|
||||
public AchievementService(AchievementStoreSingleton achievementStore, InventoryService inventoryService, MessagingService messagingService, DBContext ctx) {
|
||||
public AchievementService(AchievementStoreSingleton achievementStore, InventoryService inventoryService, MessagingService messagingService, DBContext ctx)
|
||||
{
|
||||
this.achievementStore = achievementStore;
|
||||
this.inventoryService = inventoryService;
|
||||
this.messagingService = messagingService;
|
||||
@ -149,6 +150,9 @@ namespace sodoff.Services {
|
||||
|
||||
// TODO: check trophies, etc criteria and id need apply and add to results extra reward here
|
||||
|
||||
if (viking.GameVersion <= ClientVersion.WoJS)
|
||||
messagingService.AddMessageToViking(null, viking, MessageType.Data, MessageTypeID.Achievement, MessageLevel.WhiteList, "[[Line1]]=[[Great Job! You've Earned A Ribbon, JumpStars, And Coins!]][[SubType]]=[[Ribbon]]", "[[Line1]]=[[Great Job! You've Earned A Ribbon, JumpStars, And Coins!]][[SubType]]=[[Ribbon]]", "[[Line1]]=[[Great Job! You've Earned A Ribbon, JumpStars, And Coins!]][[SubType]]=[[Ribbon]]", isPrivate: true);
|
||||
|
||||
return grantedRewards.ToArray();
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,13 @@ public class BuddyService
|
||||
|
||||
private readonly DBContext ctx;
|
||||
private readonly MessagingService messagingService;
|
||||
private readonly MMOClientService mMOClientService;
|
||||
|
||||
public BuddyService(DBContext ctx, MessagingService messagingService)
|
||||
public BuddyService(DBContext ctx, MessagingService messagingService, MMOClientService mMOClientService)
|
||||
{
|
||||
this.ctx = ctx;
|
||||
this.messagingService = messagingService;
|
||||
this.mMOClientService = mMOClientService;
|
||||
}
|
||||
|
||||
public BuddyActionResult CreateBuddyRelation(Viking viking1, Viking viking2, BuddyStatus buddyStatus1 = BuddyStatus.PendingApprovalFromOther, BuddyStatus buddyStatus2 = BuddyStatus.PendingApprovalFromSelf)
|
||||
@ -53,8 +55,11 @@ public class BuddyService
|
||||
|
||||
// if this is a buddy relationship, use MessagingService to send buddy request message to viking2
|
||||
if (buddyStatus1 == BuddyStatus.PendingApprovalFromOther && buddyStatus2 == BuddyStatus.PendingApprovalFromSelf)
|
||||
{
|
||||
messagingService.AddMessageToViking(viking1, viking2, MessageType.Data, MessageTypeID.BuddyList, MessageLevel.WhiteList, "[[Line1]]=[[{{BuddyUserName}} Wants To Add You As A Buddy!]]", "[[Line1]]=[[{{BuddyUserName}} Wants To Add You As A Buddy!]]", "[[Line1]]=[[{{BuddyUserName}} Wants To Add You As A Buddy!]]");
|
||||
|
||||
mMOClientService.SendCommandToUser(viking2.Uid.ToString(), "SBE", new string[] { "SBE", "-1", viking1.Uid.ToString(), viking2.Uid.ToString(), "1" });
|
||||
}
|
||||
|
||||
// return result
|
||||
return new BuddyActionResult
|
||||
{
|
||||
@ -77,6 +82,9 @@ public class BuddyService
|
||||
buddy.BuddyStatus2 = buddyStatus2;
|
||||
ctx.SaveChanges();
|
||||
|
||||
if ((buddyStatus1 & buddyStatus2) == BuddyStatus.Approved)
|
||||
mMOClientService.SendCommandToUser(viking.Uid.ToString(), "SBE", new string[] { "SBE", "-1", buddyViking.Uid.ToString(), viking.Uid.ToString(), "4" });
|
||||
|
||||
// return result
|
||||
return true;
|
||||
} else return false;
|
||||
@ -161,6 +169,8 @@ public class BuddyService
|
||||
ctx.Buddies.Remove(buddy);
|
||||
ctx.SaveChanges();
|
||||
|
||||
mMOClientService.SendCommandToUser(buddyViking.Uid.ToString(), "SBE", new string[] { "SBE", "-1", viking.Uid.ToString(), buddyViking.Uid.ToString(), "2" });
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
111
src/Services/MMOClientService.cs
Normal file
111
src/Services/MMOClientService.cs
Normal file
@ -0,0 +1,111 @@
|
||||
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.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 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.");
|
||||
}
|
||||
}
|
@ -11,9 +11,11 @@ namespace sodoff.Services;
|
||||
public class MessagingService
|
||||
{
|
||||
private readonly DBContext ctx;
|
||||
public MessagingService(DBContext ctx)
|
||||
private readonly MMOClientService mMOClientService;
|
||||
public MessagingService(DBContext ctx, MMOClientService mMOClientService)
|
||||
{
|
||||
this.ctx = ctx;
|
||||
this.mMOClientService = mMOClientService;
|
||||
}
|
||||
|
||||
public Model.Message AddMessageToViking(Viking? viking, Viking toViking, MessageType messageType, MessageTypeID messageTypeID, MessageLevel messageLevel, string data, string memberMessage = "", string nonMemberMessage = "", bool IsNew = true, bool IsDeleted = false, bool isReply = false, bool isPrivate = false, int parentMessageId = 0)
|
||||
@ -74,6 +76,10 @@ public class MessagingService
|
||||
ctx.Messages.Add(message);
|
||||
ctx.SaveChanges();
|
||||
|
||||
// update receiving users messages
|
||||
mMOClientService.SendCommandToUser(toViking.Uid.ToString(), "SPMN", new string[] { "SPMN" });
|
||||
mMOClientService.SendCommandToUser(toViking.Uid.ToString(), "NMP", new string[] { "NMP", "-1", "1", "1" });
|
||||
|
||||
// return constructed message
|
||||
return message;
|
||||
}
|
||||
|
@ -159,4 +159,14 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="SmartFox2X">
|
||||
<HintPath>Dlls\SmartFox2X.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Dlls\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user