mirror of
https://github.com/SoDOff-Project/sodoff.git
synced 2025-10-11 16:28:50 -07:00
Implement Realtime MMO Communication
This commit is contained in:
parent
dcefeb5fc3
commit
62387149d3
@ -4,6 +4,7 @@ public class ApiServerConfig {
|
|||||||
|
|
||||||
public string MMOAdress { get; set; } = "127.0.0.1";
|
public string MMOAdress { get; set; } = "127.0.0.1";
|
||||||
public int MMOPort { get; set; } = 9933;
|
public int MMOPort { get; set; } = 9933;
|
||||||
|
public int MMOHttpApiPort { get; set; } = 9934;
|
||||||
public uint MMOSupportMinVersion { get; set; } = 0;
|
public uint MMOSupportMinVersion { get; set; } = 0;
|
||||||
|
|
||||||
public DbProviders DbProvider { get; set; } = DbProviders.SQLite;
|
public DbProviders DbProvider { get; set; } = DbProviders.SQLite;
|
||||||
|
@ -22,6 +22,7 @@ public class ContentController : Controller {
|
|||||||
private GameDataService gameDataService;
|
private GameDataService gameDataService;
|
||||||
private DisplayNamesService displayNamesService;
|
private DisplayNamesService displayNamesService;
|
||||||
private NeighborhoodService neighborhoodService;
|
private NeighborhoodService neighborhoodService;
|
||||||
|
private MMOCommunicationService mMOCommunicationService;
|
||||||
private Random random = new Random();
|
private Random random = new Random();
|
||||||
private readonly IOptions<ApiServerConfig> config;
|
private readonly IOptions<ApiServerConfig> config;
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ public class ContentController : Controller {
|
|||||||
GameDataService gameDataService,
|
GameDataService gameDataService,
|
||||||
DisplayNamesService displayNamesService,
|
DisplayNamesService displayNamesService,
|
||||||
NeighborhoodService neighborhoodService,
|
NeighborhoodService neighborhoodService,
|
||||||
|
MMOCommunicationService mMOCommunicationService,
|
||||||
IOptions<ApiServerConfig> config
|
IOptions<ApiServerConfig> config
|
||||||
) {
|
) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
@ -48,6 +50,7 @@ public class ContentController : Controller {
|
|||||||
this.gameDataService = gameDataService;
|
this.gameDataService = gameDataService;
|
||||||
this.displayNamesService = displayNamesService;
|
this.displayNamesService = displayNamesService;
|
||||||
this.neighborhoodService = neighborhoodService;
|
this.neighborhoodService = neighborhoodService;
|
||||||
|
this.mMOCommunicationService = mMOCommunicationService;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1608,13 +1611,14 @@ public class ContentController : Controller {
|
|||||||
[Produces("application/xml")]
|
[Produces("application/xml")]
|
||||||
[Route("ContentWebService.asmx/SetScene")] // used by World of Jumpstart
|
[Route("ContentWebService.asmx/SetScene")] // used by World of Jumpstart
|
||||||
[VikingSession]
|
[VikingSession]
|
||||||
public IActionResult SetScene(Viking viking, [FromForm] string sceneName, [FromForm] string contentXml) {
|
public IActionResult SetScene(Viking viking, [FromForm] string sceneName, [FromForm] string contentXml, [FromForm] string apiToken) {
|
||||||
SceneData? existingScene = viking.SceneData.FirstOrDefault(e => e.SceneName == sceneName);
|
SceneData? existingScene = viking.SceneData.FirstOrDefault(e => e.SceneName == sceneName);
|
||||||
|
|
||||||
if(existingScene is not null)
|
if(existingScene is not null)
|
||||||
{
|
{
|
||||||
existingScene.XmlData = contentXml;
|
existingScene.XmlData = contentXml;
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
|
mMOCommunicationService.SendPacketToRoom(apiToken, sceneName + '_' + viking.Uid.ToString(), "SNE", new string[] { "SNE", "-1", contentXml, "8" });
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1634,13 +1638,14 @@ public class ContentController : Controller {
|
|||||||
[Produces("application/xml")]
|
[Produces("application/xml")]
|
||||||
[Route("ContentWebService.asmx/SetHouse")] // used by World Of Jumpstart
|
[Route("ContentWebService.asmx/SetHouse")] // used by World Of Jumpstart
|
||||||
[VikingSession]
|
[VikingSession]
|
||||||
public IActionResult SetHouse(Viking viking, [FromForm] string contentXml) {
|
public IActionResult SetHouse(Viking viking, [FromForm] string contentXml, [FromForm] string apiToken) {
|
||||||
Util.SavedData.Set(
|
Util.SavedData.Set(
|
||||||
viking,
|
viking,
|
||||||
Util.SavedData.House(),
|
Util.SavedData.House(),
|
||||||
contentXml
|
contentXml
|
||||||
);
|
);
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
|
mMOCommunicationService.SendPacketToRoom(apiToken, $"MyNeighborhood_{viking.Uid}", "SNE", new string[] { "SNE", "-1", viking.Uid.ToString(), "10" }); // hardcoding neighborhood here for now, client doesn't send a scene name here
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1648,8 +1653,8 @@ public class ContentController : Controller {
|
|||||||
[Produces("application/xml")]
|
[Produces("application/xml")]
|
||||||
[Route("ContentWebService.asmx/SetNeighbor")] // used by World Of Jumpstart
|
[Route("ContentWebService.asmx/SetNeighbor")] // used by World Of Jumpstart
|
||||||
[VikingSession(UseLock=true)]
|
[VikingSession(UseLock=true)]
|
||||||
public IActionResult SetNeighbor(Viking viking, string neighboruserid, int slot) {
|
public IActionResult SetNeighbor(Viking viking, string neighboruserid, int slot, string apiToken) {
|
||||||
return Ok(neighborhoodService.SaveNeighbors(viking, neighboruserid, slot));
|
return Ok(neighborhoodService.SaveNeighbors(viking, neighboruserid, slot, apiToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
@ -39,6 +39,7 @@ builder.Services.AddScoped<AchievementService>();
|
|||||||
builder.Services.AddScoped<GameDataService>();
|
builder.Services.AddScoped<GameDataService>();
|
||||||
builder.Services.AddScoped<ProfileService>();
|
builder.Services.AddScoped<ProfileService>();
|
||||||
builder.Services.AddScoped<NeighborhoodService>();
|
builder.Services.AddScoped<NeighborhoodService>();
|
||||||
|
builder.Services.AddScoped<MMOCommunicationService>();
|
||||||
|
|
||||||
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");
|
||||||
|
92
src/Services/MMOCommunicationService.cs
Normal file
92
src/Services/MMOCommunicationService.cs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data.Common;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using sodoff.Configuration;
|
||||||
|
using sodoff.Model;
|
||||||
|
|
||||||
|
namespace sodoff.Services;
|
||||||
|
|
||||||
|
public class MMOCommunicationService
|
||||||
|
{
|
||||||
|
public readonly DBContext dBContext;
|
||||||
|
public readonly HttpClient httpClient;
|
||||||
|
public readonly IOptions<ApiServerConfig> config;
|
||||||
|
|
||||||
|
public MMOCommunicationService(DBContext dBContext, IOptions<ApiServerConfig> options)
|
||||||
|
{
|
||||||
|
this.dBContext = dBContext;
|
||||||
|
config = options;
|
||||||
|
httpClient = new HttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendPacketToRoom(string apiToken, string roomName, string cmd, string[] args)
|
||||||
|
{
|
||||||
|
var serializedArgs = JsonSerializer.Serialize(args);
|
||||||
|
|
||||||
|
FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "apiToken", apiToken },
|
||||||
|
{ "roomName", roomName },
|
||||||
|
{ "cmd", cmd },
|
||||||
|
{ "serializedArgs", serializedArgs }
|
||||||
|
});
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = httpClient.PostAsync($"http://{config.Value.MMOAdress}:{config.Value.MMOHttpApiPort}/mmo/update/SendPacketToRoom", form)?.Result;
|
||||||
|
if (result != null && result.StatusCode == System.Net.HttpStatusCode.OK) return true;
|
||||||
|
else return false;
|
||||||
|
} catch (AggregateException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("MMO Communication Failiure. Please Investigate - " + ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendPacketToPlayer(string apiToken, string userId, string cmd, string[] args)
|
||||||
|
{
|
||||||
|
var argsSerialized = JsonSerializer.Serialize(args);
|
||||||
|
FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "apiToken", apiToken },
|
||||||
|
{ "userId", userId },
|
||||||
|
{ "cmd", cmd },
|
||||||
|
{ "serializedArgs", argsSerialized }
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = httpClient.PostAsync($"http://{config.Value.MMOAdress}:{config.Value.MMOHttpApiPort}/mmo/update/SendPacketToPlayer", form)?.Result;
|
||||||
|
if (result != null && result.StatusCode == System.Net.HttpStatusCode.OK) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
catch (AggregateException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("MMO Communication Failiure. Please Investigate - " + ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UpdateRoomVarsInRoom<T>(string apiToken, string roomName, Dictionary<string, T> vars)
|
||||||
|
{
|
||||||
|
var varsSerialized = JsonSerializer.Serialize(vars);
|
||||||
|
FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "apiToken", apiToken },
|
||||||
|
{ "roomName", roomName },
|
||||||
|
{ "serializedVars", varsSerialized }
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = httpClient.PostAsync($"http://{config.Value.MMOAdress}:{config.Value.MMOHttpApiPort}/mmo/update/UpdateRoomVarsInRoom", form)?.Result;
|
||||||
|
if (result != null && result.StatusCode == System.Net.HttpStatusCode.OK) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
catch (AggregateException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("MMO Communication Failiure. Please Investigate - " + ex.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ namespace sodoff.Services
|
|||||||
public class NeighborhoodService
|
public class NeighborhoodService
|
||||||
{
|
{
|
||||||
private readonly DBContext ctx;
|
private readonly DBContext ctx;
|
||||||
|
private readonly MMOCommunicationService mMOCommunicationService;
|
||||||
|
|
||||||
// default neighborhood slots (NPCs)
|
// default neighborhood slots (NPCs)
|
||||||
Guid slot0 = new Guid("aaaaaaaa-0000-0000-0000-000000000000");
|
Guid slot0 = new Guid("aaaaaaaa-0000-0000-0000-000000000000");
|
||||||
@ -18,12 +19,14 @@ namespace sodoff.Services
|
|||||||
Guid slot3 = new Guid("dddddddd-0000-0000-0000-000000000000");
|
Guid slot3 = new Guid("dddddddd-0000-0000-0000-000000000000");
|
||||||
Guid slot4 = new Guid("eeeeeeee-0000-0000-0000-000000000000");
|
Guid slot4 = new Guid("eeeeeeee-0000-0000-0000-000000000000");
|
||||||
|
|
||||||
public NeighborhoodService(DBContext ctx) {
|
public NeighborhoodService(DBContext ctx, MMOCommunicationService mMOCommunicationService) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
this.mMOCommunicationService = mMOCommunicationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SaveNeighbors(Viking viking, string neighborUid, int slot) {
|
public bool SaveNeighbors(Viking viking, string neighborUid, int slot, string apiToken) {
|
||||||
Model.Neighborhood? neighborhood = viking.Neighborhood;
|
Model.Neighborhood? neighborhood = viking.Neighborhood;
|
||||||
|
Dictionary<string, string> neighborRoomVars = new Dictionary<string, string>();
|
||||||
|
|
||||||
if (neighborhood == null) // if viking has no neighborhood yet, create a default one
|
if (neighborhood == null) // if viking has no neighborhood yet, create a default one
|
||||||
viking.Neighborhood = new Model.Neighborhood {
|
viking.Neighborhood = new Model.Neighborhood {
|
||||||
@ -39,21 +42,28 @@ namespace sodoff.Services
|
|||||||
switch (slot) {
|
switch (slot) {
|
||||||
case 0:
|
case 0:
|
||||||
viking.Neighborhood.Slot0 = new Guid(neighborUid);
|
viking.Neighborhood.Slot0 = new Guid(neighborUid);
|
||||||
|
neighborRoomVars.Add("S0", viking.Neighborhood.Slot0.ToString());
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
viking.Neighborhood.Slot1 = new Guid(neighborUid);
|
viking.Neighborhood.Slot1 = new Guid(neighborUid);
|
||||||
|
neighborRoomVars.Add("S1", viking.Neighborhood.Slot1.ToString());
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
viking.Neighborhood.Slot2 = new Guid(neighborUid);
|
viking.Neighborhood.Slot2 = new Guid(neighborUid);
|
||||||
|
neighborRoomVars.Add("S2", viking.Neighborhood.Slot2.ToString());
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
viking.Neighborhood.Slot3 = new Guid(neighborUid);
|
viking.Neighborhood.Slot3 = new Guid(neighborUid);
|
||||||
|
neighborRoomVars.Add("S3", viking.Neighborhood.Slot3.ToString());
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
viking.Neighborhood.Slot4 = new Guid(neighborUid);
|
viking.Neighborhood.Slot4 = new Guid(neighborUid);
|
||||||
|
neighborRoomVars.Add("S4", viking.Neighborhood.Slot4.ToString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mMOCommunicationService.UpdateRoomVarsInRoom(apiToken, $"MyNeighborhood_{viking.Uid}", neighborRoomVars); // once again hardcoding neighborhood
|
||||||
|
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user