Skip to content

Commit

Permalink
working gossip, why? who knows
Browse files Browse the repository at this point in the history
  • Loading branch information
SwiftAusterity committed Jul 3, 2018
1 parent ec3378f commit a400392
Show file tree
Hide file tree
Showing 23 changed files with 362 additions and 175 deletions.
7 changes: 7 additions & 0 deletions Gossip.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="clientId" value="bc691110-be48-4a33-99c9-db0f613e9e0d"/>
<add key="clientSecret" value="8fd8d24c-d5e5-49fa-9dc6-eb911e303ae8"/>
</appSettings>
</configuration>
8 changes: 4 additions & 4 deletions NetMud.CentralControl/Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public static class Processor
{
private static ObjectCache globalCache = MemoryCache.Default;
private static CacheItemPolicy globalPolicy = new CacheItemPolicy();
private static string cancellationTokenCacheKeyFormat = "AsyncCancellationToken.{0}";
private static string subscriptionLoopCacheKeyFormat = "SubscriptionLoop.{0}";
private static readonly string cancellationTokenCacheKeyFormat = "AsyncCancellationToken.{0}";
private static readonly string subscriptionLoopCacheKeyFormat = "SubscriptionLoop.{0}";
private static int _maxPulseCount = 18000; //half an hour

/// <summary>
Expand Down Expand Up @@ -86,11 +86,11 @@ public static void StartSingeltonChainedLoop(string designator, int rampupDelay,

StoreCancellationToken(designator, cancelTokenSource);

Func<bool> loopedProcess = () =>
bool loopedProcess()
{
StartLoop(workProcess, rampupDelay);
return true;
};
}

var newLoop = new Task<bool>(loopedProcess, cancelTokenSource.Token, TaskCreationOptions.LongRunning);

Expand Down
84 changes: 84 additions & 0 deletions NetMud.Commands/Comm/Gossip.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using NetMud.Commands.Attributes;
using NetMud.Communication.Messaging;
using NetMud.Data.System;
using NetMud.DataAccess.Cache;
using NetMud.DataStructure.Base.Entity;
using NetMud.DataStructure.Base.System;
using NetMud.DataStructure.SupportingClasses;
using NutMud.Commands.Attributes;
using System.Collections.Generic;
using System.Linq;

namespace NetMud.Commands.Comm
{
[CommandKeyword("gossip", false)]
[CommandPermission(StaffRank.Player)]
[CommandParameter(CommandUsage.Subject, typeof(string), new CacheReferenceType[] { CacheReferenceType.Text }, false)]
[CommandRange(CommandRangeType.Touch, 0)]
public class Gossip : CommandPartial
{
/// <summary>
/// All Commands require a generic constructor
/// </summary>
public Gossip()
{
//Generic constructor for all IHelpfuls is needed
}

/// <summary>
/// Executes this command
/// </summary>
public override void Execute()
{
var sb = new List<string>
{
string.Format("You gossip '{0}'", Subject)
};

var toActor = new Message(MessagingType.Audible, new Occurrence() { Strength = 1 })
{
Override = sb
};

//TODO: language outputs
var messagingObject = new MessageCluster(toActor);

messagingObject.ExecuteMessaging(Actor, null, null, null, null);

var gossipClient = LiveCache.Get<IGossipClient>("GossipWebClient");

var userName = Actor.DataTemplateName;

if (Actor.GetType().GetInterfaces().Contains(typeof(IPlayer)))
userName = ((IPlayer)Actor).AccountHandle;

gossipClient.SendMessage(userName, Subject.ToString());
}

/// <summary>
/// Renders syntactical help for the command, invokes automatically when syntax is bungled
/// </summary>
/// <returns>string</returns>
public override IEnumerable<string> RenderSyntaxHelp()
{
var sb = new List<string>
{
"Valid Syntax: gossip &lt;text&gt;",
};

return sb;
}

/// <summary>
/// The custom body of help text
/// </summary>
public override string HelpText
{
get
{
return string.Format("Gossip allows you to speak over the gossip inter-mud network.");
}
set { }
}
}
}
1 change: 1 addition & 0 deletions NetMud.Commands/NetMud.Commands.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Compile Include="Attributes\CommandPartial.cs" />
<Compile Include="Attributes\CommandPermissionAttribute.cs" />
<Compile Include="Attributes\CommandRangeAttribute.cs" />
<Compile Include="Comm\Gossip.cs" />
<Compile Include="Comm\Say.cs" />
<Compile Include="EntityManipulation\Drop.cs" />
<Compile Include="EntityManipulation\Get.cs" />
Expand Down
16 changes: 16 additions & 0 deletions NetMud.DataStructure/Base/System/IGossipClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetMud.DataStructure.Base.System
{
public interface IGossipClient
{
string CacheKey { get; }
void Launch();
void Shutdown();
void SendMessage(string userName, string messageBody, string channel = "gossip");
}
}
1 change: 1 addition & 0 deletions NetMud.DataStructure/NetMud.DataStructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
<Compile Include="Base\System\CacheType.cs" />
<Compile Include="Base\System\ConfigDataType.cs" />
<Compile Include="Base\System\IConfigData.cs" />
<Compile Include="Base\System\IGossipClient.cs" />
<Compile Include="Base\System\IKeyedData.cs" />
<Compile Include="Behaviors\Actionable\ICanBeAffected.cs" />
<Compile Include="Behaviors\Actionable\ICanBeWounded.cs" />
Expand Down
10 changes: 4 additions & 6 deletions NetMud.Gossip/App.Expected.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="clientId" value=""/>
<add key="clientSecret" value=""/>
</appSettings>
</configuration>
<appSettings>
<add key="clientId" value=""/>
<add key="clientSecret" value=""/>
</appSettings>
179 changes: 179 additions & 0 deletions NetMud.Gossip/GossipClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
using NetMud.DataAccess;
using NetMud.DataAccess.Cache;
using NetMud.DataStructure.Base.Entity;
using NetMud.DataStructure.Base.System;
using NetMud.Gossip.Messaging;
using NetMud.Utility;
using System;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using WebSocketSharp;

namespace NetMud.Gossip
{
public class GossipClient : IGossipClient
{
/// <summary>
/// The format the cachekeys for the comms objects take
/// </summary>
public string CacheKey => "GossipWebClient";

private WebSocket MyClient { get; set; }

/// <summary>
/// Registers this for a service on a port
/// </summary>
/// <param name="portNumber">the port it is listening on</param>
public void Launch()
{
try
{
//Connect to the gossip service
MyClient = new WebSocket("wss://gossip.haus/socket");

MyClient.Log.Level = LogLevel.Error;
MyClient.Log.Output = (data, eventing) => LoggingUtility.Log(data.Message, LogChannels.GossipServer, true);

MyClient.OnMessage += (sender, e) => OnMessage(sender, e);

MyClient.OnOpen += (sender, e) => OnOpen(sender, e);

MyClient.Connect();

LiveCache.Add(this, CacheKey);
}
catch (Exception ex)
{
LoggingUtility.LogError(ex, LogChannels.GossipServer);
}
}

/// <summary>
/// Handles initial connection
/// </summary>
private void OnOpen(object sender, EventArgs e)
{
var authenticateBlock = new Authentication();

var auth = new TransportMessage()
{
Event = authenticateBlock.Type,
Payload = authenticateBlock
};

MyClient.Send(Serialize(auth));
}

private void OnMessage(object sender, MessageEventArgs e)
{
if (e.IsPing)
return; //pong maybe?
else
{
LoggingUtility.Log(e.Data, LogChannels.GossipServer, true);
var newReply = DeSerialize(e.Data);

switch (newReply.Event)
{
case "messages/direct":
var validPlayer = LiveCache.GetAll<IPlayer>().FirstOrDefault(player => player.AccountHandle.Equals(newReply.Payload.name) && player.Descriptor != null);

if (validPlayer != null)
validPlayer.Descriptor.SendWrapper(newReply.Payload.MessageBody);
break;
case "messages/broadcast":
var messageText = newReply.Payload.message.Value;
var messageSender = newReply.Payload.name.Value;
var source = newReply.Payload.game.Value;
var channel = newReply.Payload.channel.Value;

if (!string.IsNullOrWhiteSpace(messageText))
{
var validPlayers = LiveCache.GetAll<IPlayer>().Where(player => player.Descriptor != null);
foreach (var player in validPlayers)
player.WriteTo(new string[] { string.Format("{0}@{1} {3}s, '{2}'", messageSender, source, messageText, channel) });
}
break;
case "channels/subscribed":
break;
default:
//do nothing
break;
}
}
}

public void SendMessage(string userName, string messageBody, string channel = "gossip")
{
var messageBlock = new NewMessage()
{
ChannelName = channel,
MessageBody = messageBody,
Username = userName
};

var message = new TransportMessage()
{
Event = messageBlock.Type,
Payload = messageBlock
};

MyClient.Send(Serialize(message));
}

public void Shutdown()
{
var service = GetActiveService();

if (service != null)
service.Close();
}

public WebSocket GetActiveService()
{
try
{
return LiveCache.Get<WebSocket>(CacheKey);
}
catch (Exception ex)
{
LoggingUtility.LogError(ex, false);
}

return null;
}

/// <summary>
/// Serialize this live entity to a json string
/// </summary>
/// <returns>json string</returns>
private string Serialize(TransportMessage message)
{
var serializer = SerializationUtility.GetSerializer();

var sb = new StringBuilder();
var writer = new StringWriter(sb);

serializer.Serialize(writer, message);

return sb.ToString();
}

/// <summary>
/// Deserialize a json string into this entity
/// </summary>
/// <param name="jsonData">string to deserialize</param>
/// <returns>the entity</returns>
private TransportMessage DeSerialize(string jsonData)
{
var serializer = SerializationUtility.GetSerializer();

var reader = new StringReader(jsonData);

return serializer.Deserialize(reader, typeof(TransportMessage)) as TransportMessage;
}
}

}
Loading

0 comments on commit a400392

Please sign in to comment.