NWN2-AI-Server/nwn2ai_onmoduleload/nwn2ai_onmoduleload.cs

169 lines
5.6 KiB
C#
Raw Normal View History

2015-04-13 20:56:36 +00:00
//
// This script serves as a basis for new scripts. New scripts can copy this
// source file to start out.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Reflection.Emit;
using CLRScriptFramework;
using NWScript;
using NWScript.ManagedInterfaceLayer.NWScriptManagedInterface;
using NWEffect = NWScript.NWScriptEngineStructure0;
using NWEvent = NWScript.NWScriptEngineStructure1;
using NWLocation = NWScript.NWScriptEngineStructure2;
using NWTalent = NWScript.NWScriptEngineStructure3;
using NWItemProperty = NWScript.NWScriptEngineStructure4;
using System.Threading;
2015-04-14 21:24:56 +00:00
using System.IO;
using System.Net;
using System.Net.Sockets;
2015-04-21 21:45:52 +00:00
using Newtonsoft.Json;
2015-04-13 20:56:36 +00:00
namespace CLRScript
{
2015-04-17 19:36:14 +00:00
public partial class nwn2ai_onmoduleload : CLRScriptBase, ICLRScriptImplementation, IGeneratedScriptProgram
2015-04-13 20:56:36 +00:00
{
2015-04-17 19:36:14 +00:00
public nwn2ai_onmoduleload([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
2015-04-13 20:56:36 +00:00
{
InitScript(Intrinsics, Host);
}
2015-04-17 19:36:14 +00:00
private nwn2ai_onmoduleload([In] nwn2ai_onmoduleload Other)
2015-04-13 20:56:36 +00:00
{
InitScript(Other);
LoadScriptGlobals(Other.SaveScriptGlobals());
}
//
// Include the list of types for parameters to the main function here.
// An empty list means no parameters.
//
public static Type[] ScriptParameterTypes = { };
2015-04-17 19:36:14 +00:00
StreamWriter debugFile;
2015-04-13 20:56:36 +00:00
public Int32 ScriptMain([In] object[] ScriptParameters, [In] Int32 DefaultReturnCode)
{
2015-04-17 19:36:14 +00:00
debugFile = File.AppendText("nwnx4\\customlog.txt");
Debug("====================================> Start");
sockBufferIn = new Queue<Tuple<string,Socket>>();
sockClients = new Dictionary<string,Socket>();
SocketConfigure();
2015-04-14 21:24:56 +00:00
AssignCommand(OBJECT_SELF, delegate() { ActionSpeakString("Start!", TALKVOLUME_TALK); });
DelayCommand(0.5f, Heartbeat);
2015-04-14 21:24:56 +00:00
return DefaultReturnCode;
}
2015-04-14 21:24:56 +00:00
public void Heartbeat()
{
2015-04-21 21:45:52 +00:00
ActionSpeakString("hb", TALKVOLUME_SHOUT);
2015-04-14 21:24:56 +00:00
DelayCommand(0.5f, Heartbeat);
//Process queued requests
2015-04-27 21:10:07 +00:00
//Debug("Proc cmds");
2015-04-21 21:45:52 +00:00
while(sockBufferIn.Count>0){
Tuple<string, Socket> req = sockBufferIn.Dequeue();
2015-04-27 21:10:07 +00:00
var socket = req.Item2;
2015-04-21 21:45:52 +00:00
var json = JsonConvert.DeserializeObject<dynamic>(req.Item1);
2015-04-27 21:10:07 +00:00
//TODO: check if json correctly parsed
2015-04-21 21:45:52 +00:00
switch ((string)json.action) {
case "bind": {
Debug("Bind request to '"+json.target+"'");
2015-04-27 21:10:07 +00:00
try {
if (!sockClients.ContainsKey((string)json.target)) {
sockClients.Add((string)json.target, socket);
socket.Send(Encoding.UTF8.GetBytes(
"{\"action\":\"bindack\", \"result\":\"ok\"}"
));
//handle env
}
else {
socket.Send(Encoding.UTF8.GetBytes(
"{\"action\":\"bindack\", \"result\":\"failed\", \"message\":\"Socket already binded with this NPC\"}"
));
}
2015-04-21 21:45:52 +00:00
}
2015-04-27 21:10:07 +00:00
catch (Exception e) {
socket.Send(Encoding.UTF8.GetBytes(
"{\"action\":\"bindack\", \"result\":\"failed\", \"message\":\"Thrown exception: "+e.ToString().Replace("\"","\\\"")+"\"}"
));
2015-04-21 21:45:52 +00:00
}
2015-04-27 21:10:07 +00:00
}break;
case "decision": {
}break;
2015-04-21 21:45:52 +00:00
}
}
2015-04-14 21:24:56 +00:00
}
2015-04-13 20:56:36 +00:00
void SocketConfigure()
{
sockServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 8080);
sockServer.Bind(iep);
sockServer.Listen(10);
2015-04-13 20:56:36 +00:00
sockServer.BeginAccept(new AsyncCallback(RequestHandler), null);
2015-04-13 20:56:36 +00:00
}
void RequestHandler(IAsyncResult state)
{
2015-04-18 08:17:46 +00:00
Socket sockClient = sockServer.EndAccept(state);
sockServer.BeginAccept(new AsyncCallback(RequestHandler), null);
sockClient.Blocking = true;
while (sockClient.Connected) {
2015-04-27 21:10:07 +00:00
if (sockClient.Available > 0) {
2015-04-27 21:10:07 +00:00
byte[] rawData = new byte[sockClient.Available];
sockClient.Receive(rawData, rawData.Length, 0);
string data = Encoding.UTF8.GetString(rawData);
2015-04-27 21:10:07 +00:00
Debug("Queued "+data);
sockBufferIn.Enqueue(new Tuple<string,Socket>(data, sockClient));
}
2015-04-27 21:10:07 +00:00
Thread.Sleep(10);
}
2015-04-18 08:17:46 +00:00
2015-04-27 21:10:07 +00:00
//Remove stored bind
var sock = sockClients.First(kvp => kvp.Value==sockClient);
sockClients.Remove(sock.Key);
}
Socket sockServer;
Queue<Tuple<string,Socket>> sockBufferIn;//Request & client
2015-04-27 21:10:07 +00:00
Dictionary<string, Socket> sockClients;//PNJ tag => Client socket
2015-04-17 19:36:14 +00:00
private void Debug(string msg){
debugFile.WriteLine(DateTime.Now.ToLongTimeString()+": "+msg);
debugFile.Flush();
}
2015-04-13 20:56:36 +00:00
}
}