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
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ __pycache__/
|
|||||||
sodoff.db
|
sodoff.db
|
||||||
sodoff.db-shm
|
sodoff.db-shm
|
||||||
sodoff.db-wal
|
sodoff.db-wal
|
||||||
|
src/Dlls/SmartFox2X.dll
|
@ -1754,6 +1754,7 @@ public class ContentController : Controller {
|
|||||||
{
|
{
|
||||||
existingScene.XmlData = contentXml;
|
existingScene.XmlData = contentXml;
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
|
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1765,6 +1766,7 @@ public class ContentController : Controller {
|
|||||||
};
|
};
|
||||||
viking.SceneData.Add(sceneData);
|
viking.SceneData.Add(sceneData);
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
|
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ builder.Services.AddSingleton<ItemService>();
|
|||||||
builder.Services.AddSingleton<StoreService>();
|
builder.Services.AddSingleton<StoreService>();
|
||||||
builder.Services.AddSingleton<DisplayNamesService>();
|
builder.Services.AddSingleton<DisplayNamesService>();
|
||||||
builder.Services.AddSingleton<MMOConfigService>();
|
builder.Services.AddSingleton<MMOConfigService>();
|
||||||
|
builder.Services.AddSingleton<MMOClientService>();
|
||||||
builder.Services.AddSingleton<WorldIdService>();
|
builder.Services.AddSingleton<WorldIdService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<KeyValueService>();
|
builder.Services.AddScoped<KeyValueService>();
|
||||||
@ -44,6 +45,8 @@ builder.Services.AddScoped<ModerationService>();
|
|||||||
builder.Services.AddScoped<MessagingService>();
|
builder.Services.AddScoped<MessagingService>();
|
||||||
builder.Services.AddScoped<BuddyService>();
|
builder.Services.AddScoped<BuddyService>();
|
||||||
|
|
||||||
|
builder.Services.AddHostedService<MMOClientService>(provider => provider.GetService<MMOClientService>());
|
||||||
|
|
||||||
bool assetServer = builder.Configuration.GetSection("AssetServer").GetValue<bool>("Enabled");
|
bool assetServer = builder.Configuration.GetSection("AssetServer").GetValue<bool>("Enabled");
|
||||||
string assetIP = builder.Configuration.GetSection("AssetServer").GetValue<string>("ListenIP");
|
string assetIP = builder.Configuration.GetSection("AssetServer").GetValue<string>("ListenIP");
|
||||||
int assetPort = builder.Configuration.GetSection("AssetServer").GetValue<int>("Port");
|
int assetPort = builder.Configuration.GetSection("AssetServer").GetValue<int>("Port");
|
||||||
|
@ -12,7 +12,8 @@ namespace sodoff.Services {
|
|||||||
private MessagingService messagingService;
|
private MessagingService messagingService;
|
||||||
public readonly DBContext ctx;
|
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.achievementStore = achievementStore;
|
||||||
this.inventoryService = inventoryService;
|
this.inventoryService = inventoryService;
|
||||||
this.messagingService = messagingService;
|
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
|
// 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();
|
return grantedRewards.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,13 @@ public class BuddyService
|
|||||||
|
|
||||||
private readonly DBContext ctx;
|
private readonly DBContext ctx;
|
||||||
private readonly MessagingService messagingService;
|
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.ctx = ctx;
|
||||||
this.messagingService = messagingService;
|
this.messagingService = messagingService;
|
||||||
|
this.mMOClientService = mMOClientService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuddyActionResult CreateBuddyRelation(Viking viking1, Viking viking2, BuddyStatus buddyStatus1 = BuddyStatus.PendingApprovalFromOther, BuddyStatus buddyStatus2 = BuddyStatus.PendingApprovalFromSelf)
|
public BuddyActionResult CreateBuddyRelation(Viking viking1, Viking viking2, BuddyStatus buddyStatus1 = BuddyStatus.PendingApprovalFromOther, BuddyStatus buddyStatus2 = BuddyStatus.PendingApprovalFromSelf)
|
||||||
@ -53,7 +55,10 @@ public class BuddyService
|
|||||||
|
|
||||||
// if this is a buddy relationship, use MessagingService to send buddy request message to viking2
|
// if this is a buddy relationship, use MessagingService to send buddy request message to viking2
|
||||||
if (buddyStatus1 == BuddyStatus.PendingApprovalFromOther && buddyStatus2 == BuddyStatus.PendingApprovalFromSelf)
|
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!]]");
|
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 result
|
||||||
return new BuddyActionResult
|
return new BuddyActionResult
|
||||||
@ -77,6 +82,9 @@ public class BuddyService
|
|||||||
buddy.BuddyStatus2 = buddyStatus2;
|
buddy.BuddyStatus2 = buddyStatus2;
|
||||||
ctx.SaveChanges();
|
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 result
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
@ -161,6 +169,8 @@ public class BuddyService
|
|||||||
ctx.Buddies.Remove(buddy);
|
ctx.Buddies.Remove(buddy);
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
|
|
||||||
|
mMOClientService.SendCommandToUser(buddyViking.Uid.ToString(), "SBE", new string[] { "SBE", "-1", viking.Uid.ToString(), buddyViking.Uid.ToString(), "2" });
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
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
|
public class MessagingService
|
||||||
{
|
{
|
||||||
private readonly DBContext ctx;
|
private readonly DBContext ctx;
|
||||||
public MessagingService(DBContext ctx)
|
private readonly MMOClientService mMOClientService;
|
||||||
|
public MessagingService(DBContext ctx, MMOClientService mMOClientService)
|
||||||
{
|
{
|
||||||
this.ctx = ctx;
|
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)
|
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.Messages.Add(message);
|
||||||
ctx.SaveChanges();
|
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 constructed message
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
@ -159,4 +159,14 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="SmartFox2X">
|
||||||
|
<HintPath>Dlls\SmartFox2X.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Dlls\" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user