Skip to content

Commit

Permalink
Merge pull request #1 from PrashantMohta/databackend
Browse files Browse the repository at this point in the history
In memory data storage backend
  • Loading branch information
PrashantMohta committed Jul 17, 2022
2 parents ca8999d + a614dce commit 9d8386e
Show file tree
Hide file tree
Showing 15 changed files with 462 additions and 9 deletions.
3 changes: 2 additions & 1 deletion Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ namespace HkmpPouch
{
public static class Constants{
public static string Name = "HkmpPouch";
public static string Version = "0.2.0";
public static string Version = "0.2.0"; // given to HKMP bump only when API is incompatible
public static string ActualVersion = "0.3.0";

}
}
2 changes: 2 additions & 0 deletions GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
global using System.Collections;
global using System.Collections.Generic;
global using UnityEngine;
global using static HkmpPouch.Platform;
global using static HkmpPouch.Settings;
7 changes: 5 additions & 2 deletions HKMP/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ public class Client : ClientAddon {
internal event EventHandler<RecievedEventArgs> OnRecieve;

public Client() {
LoadSettings();
Instance = this;
}
internal void send(ushort fromPlayer,ushort toPlayer,string _mod,string _eventName,string _eventData,bool _rebroadcast = false, bool _broadcastToAll = false ,bool _reliable = false,bool sameScene = false){
if(!clientApi.NetClient.IsConnected){
return;
}
Modding.Logger.LogDebug("client send" + _eventName);
Platform.LogDebug($"{_mod} Client send {_eventName} | {_eventData}");
var netSender = clientApi.NetClient.GetNetworkSender<Packets>(Instance);

// SendCollectionData using the given packet ID
Expand All @@ -40,13 +41,15 @@ public override void Initialize(IClientApi _clientApi){
netReceiver.RegisterPacketHandler<GenericPacket>(
Packets.GenericPacket,
packetData => {
Modding.Logger.LogDebug($"Client recieve | {packetData.mod} : {packetData.eventName} [{packetData.eventData}]");
Platform.LogDebug($"{packetData.mod} Client recieve {packetData.eventName} | {packetData.eventData}");
//broadcast event to all client addons
OnRecieve?.Invoke(this,new RecievedEventArgs{
packet = packetData
});
}
);
HkmpPouch.Ready();
Platform.Log($"Pouch Client Addon Version {Constants.ActualVersion} Ready");
}

protected override string Name => Constants.Name;
Expand Down
18 changes: 18 additions & 0 deletions HKMP/Data/AppendOnlyList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace HkmpPouch{
public class ListItem{
public int ttl;
public DateTime insertedOn;
public string value;
}
public class AppendOnlyListUpdateEventArgs : EventArgs {
public List<string> data;
}

public class AppendOnlyListEvents{
public static string ADD = "|La"; //pipe Append Only List Add
public static string ADDED = "|LA"; //pipe Append Only List Added New Element
public static string GETALL = "|Lg"; //pipe Append Only List Get All
public static string GOTALL = "|LG"; //pipe Append Only List Got All (for client)
}

}
52 changes: 52 additions & 0 deletions HKMP/Data/Client/AppendOnlyList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using HkmpPouch;
using Newtonsoft.Json;
namespace HkmpPouch.PouchDataClient{

public class AppendOnlyList{
public string Name;
public List<string> listData = new();
public event EventHandler<AppendOnlyListUpdateEventArgs> OnUpdate;
private HkmpPipe pipe;

public AppendOnlyList(HkmpPipe pipe,string name){
this.pipe = pipe;
this.Name = name;
pipe.OnRecieve += HandleEvent;
}

public void HandleEvent(System.Object _, RecievedEventArgs args){
var packet = args.packet;
if(!packet.eventData.StartsWith($"{Name}|")){ return; }
if(packet.eventName == AppendOnlyListEvents.ADDED){
var data = packet.eventData.Split(new Char[] {'|'},2);
var item = data[1];
listData.Add(item);
OnUpdate?.Invoke(this,new AppendOnlyListUpdateEventArgs{
data = this.listData
});

}
if(packet.eventName == AppendOnlyListEvents.GOTALL){
var data = packet.eventData.Split(new Char[] {'|'},2);
listData = JsonConvert.DeserializeObject<List<string>>(data[1]);
OnUpdate?.Invoke(this,new AppendOnlyListUpdateEventArgs{
data = this.listData
});
}
}

public void Add(string item,int ttl){
// send add command to server
this.pipe.Send(0,0,AppendOnlyListEvents.ADD,$"{this.Name}|{ttl}|{item}",false,false,true,false);
}

public void GetAll(){
// send getAll command to server
this.pipe.Send(0,0,AppendOnlyListEvents.GETALL,this.Name,false,false,true,false);
}
public void Destory(){
pipe.OnRecieve -= HandleEvent;
}

}
}
48 changes: 48 additions & 0 deletions HKMP/Data/Client/Counter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using HkmpPouch;
namespace HkmpPouch.PouchDataClient{

public class Counter{
public string Name;
public int Count {get; private set;}
public event EventHandler<CounterUpdateEventArgs> OnUpdate;
private HkmpPipe pipe;

public Counter(HkmpPipe pipe,string name){
this.pipe = pipe;
this.Name = name;
this.Count = 0;
pipe.OnRecieve += HandleEvent;
}

public void HandleEvent(System.Object _, RecievedEventArgs args){
var packet = args.packet;
if(packet.eventName == CounterEvents.UPDATE){
var data = packet.eventData.Split('|');
if(Name == data[0]) {
this.Count = Int32.Parse(data[1]);
OnUpdate?.Invoke(this,new CounterUpdateEventArgs{
Count = this.Count
});
}
}
}

public void Get(){
this.pipe.Send(0,0,CounterEvents.GET,this.Name,false,false,true,false);
}
public void Increment(ushort value = 1){
// send increment command to server
this.pipe.Send(0,0,CounterEvents.INCREMENT,$"{this.Name}|{value}",false,false,true,false);
}

public void Decrement(ushort value = 1){
// send decrement command to server
this.pipe.Send(0,0,CounterEvents.DECREMENT,$"{this.Name}|{value}",false,false,true,false);
}

public void Destroy(){
pipe.OnRecieve -= HandleEvent;
}
}

}
14 changes: 14 additions & 0 deletions HKMP/Data/Counter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace HkmpPouch{

public class CounterUpdateEventArgs : EventArgs {
public int Count;
}

public class CounterEvents{
public static string GET = "|CG"; // pipe counter get
public static string UPDATE = "|CU"; //pipe counter update
public static string INCREMENT = "|CI"; //pipe counter Increment
public static string DECREMENT = "|CD"; //pipe counter Decrement
}

}
75 changes: 75 additions & 0 deletions HKMP/Data/Server/AppendOnlyList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Timers;

namespace HkmpPouch.PouchDataServer{

public class AppendOnlyList{
public string Name;
public string modName;
private List<ListItem> data = new();

private bool pendingPrune = false;
private static Timer EventTimer = new Timer(1000);


public AppendOnlyList(string modName, string name){
this.Name = name;
this.modName = modName;
AppendOnlyList.EventTimer.Elapsed += BatchedPrune;
AppendOnlyList.EventTimer.AutoReset = true;
AppendOnlyList.EventTimer.Enabled = true;
}

public void BatchedPrune(System.Object source, ElapsedEventArgs e){
if(!this.pendingPrune) {return;}
Prune();
}

public void Prune(){
data = data.Where(item => {
return (DateTime.Now - item.insertedOn).TotalSeconds < item.ttl;
}).ToList();
this.pendingPrune = false;
}

public void Add(ListItem item){
this.pendingPrune = true;
data.Add(item);
UpdateClientsWithLatestData(item);
}

public ListItem LastItem(){
Prune();
if(data.Count == 0){
return null;
}
return data[data.Count - 1];
}

public string SerialiseItems(){
Prune();
if(data.Count == 0){
return "";
}

return JsonConvert.SerializeObject(data.Select( item => item.value));
}

public void UpdateClientWithAllData(ushort toPlayer){
var serialisedItems = SerialiseItems();

if(serialisedItems != ""){
Server.Instance.send(0,toPlayer,this.modName,AppendOnlyListEvents.GOTALL,$"{this.Name}|{serialisedItems}",false,false,true);
} else {
Platform.LogDebug($"{modName} List {Name} Has no items to send");
}
}
public void UpdateClientsWithLatestData(ListItem lastItem){
if(lastItem != null){
Server.Instance.sendToAll(this.modName,AppendOnlyListEvents.ADDED,$"{this.Name}|{lastItem.value}",true);
}
}
}
}
43 changes: 43 additions & 0 deletions HKMP/Data/Server/Counter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Timers;
namespace HkmpPouch.PouchDataServer{

public class Counter{
public string Name;
public string modName;
public int Count {get; private set;}
private bool pendingUpdates = false;
private static Timer EventTimer = new Timer(500);
public Counter(string modName, string name){
this.Count = 0;
this.Name = name;
this.modName = modName;
Counter.EventTimer.Elapsed += BatchUpdateClients;
Counter.EventTimer.AutoReset = true;
Counter.EventTimer.Enabled = true;
}

public void BatchUpdateClients(System.Object source, ElapsedEventArgs e){
if(!pendingUpdates){ return;}
UpdateClients();
pendingUpdates = false;
}

public void UpdateClients(){
// send updated value to clients
Server.Instance.sendToAll(this.modName,CounterEvents.UPDATE,$"{this.Name}|{this.Count}",true);
}

public void UpdateClient(ushort toPlayer){
Server.Instance.send(0,toPlayer,this.modName,CounterEvents.UPDATE,$"{this.Name}|{this.Count}",false,false,true);
}
public void Increment(ushort value){
this.Count += value;
this.pendingUpdates = true;
}

public void Decrement(ushort value){
this.Count -= value;
this.pendingUpdates = true;
}
}
}
63 changes: 63 additions & 0 deletions HKMP/Data/Server/PouchData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
namespace HkmpPouch.PouchDataServer{
public class PouchData{
public string modName;
private Dictionary<string,Counter> Counters = new();
private Dictionary<string,AppendOnlyList> AppendOnlyLists = new();

public PouchData(string modName){
this.modName = modName;
Server.Instance.OnRecieve += HandleEvent;
}
public void HandleEvent(System.Object _, RecievedEventArgs args){

if(Counters == null){
Counters = new();
}
if(AppendOnlyLists == null){
AppendOnlyLists = new();
}

var packet = args.packet;
if(packet.mod != modName){ return; }
Platform.LogDebug($"{packet.mod} PouchData recieve {packet.eventName} = {packet.eventData}");

if(packet.eventName == CounterEvents.INCREMENT || packet.eventName == CounterEvents.DECREMENT || packet.eventName == CounterEvents.GET){
Counter c;
var data = packet.eventData.Split(new Char[] {'|'},2);
var counterName = data[0];
if(!Counters.TryGetValue(counterName,out c)){
c = new Counter(packet.mod,counterName);
Counters[counterName] = c;
}
if(packet.eventName == CounterEvents.GET){
c.UpdateClient(packet.fromPlayer);
}
if(packet.eventName == CounterEvents.INCREMENT){
c.Increment(ushort.Parse(data[1]));
}
if(packet.eventName == CounterEvents.DECREMENT){
c.Decrement(ushort.Parse(data[1]));
}
}
if(packet.eventName == AppendOnlyListEvents.ADD || packet.eventName == AppendOnlyListEvents.GETALL){
AppendOnlyList a;
var data = packet.eventData.Split(new Char[] {'|'},3);
var listName = data[0];
if(!AppendOnlyLists.TryGetValue(listName,out a)){
a = new AppendOnlyList(packet.mod,listName);
AppendOnlyLists[listName] = a;
}
if(packet.eventName == AppendOnlyListEvents.ADD){
a.Add(new ListItem{
insertedOn = DateTime.Now,
ttl = Int32.Parse(data[1]),
value = data[2]
});
}
if(packet.eventName == AppendOnlyListEvents.GETALL){
a.UpdateClientWithAllData(packet.fromPlayer);
}
}
}
}
}
Loading

0 comments on commit 9d8386e

Please sign in to comment.