Malformed Syslog Packet when using LEEF format - c#

I'm using SyslogNet library to send SIEM Syslog message from my app to 3rd party vendors SIEM system in LEEF format (in this it's QRadar).
However, I the message doesn't get sent and nowhere the procedure produce any exception.
I can see and confirm that the string correlates to the correct template/format according to Rfc5424 for LEEF messages (see example below the code).
The only indication that the message was not sent properly is a WireShark trace showing the that the message was consisted of only a few bytes and more importantly is considered a malformed packet:
The code is as follows:
using System.IO;
using System.Text;
using System.Reflection;
using SyslogNet.Client;
using SyslogNet.Client.Serialization;
using SyslogNet.Client.Transport;
using Severity = SyslogNet.Client.Severity;
namespace Providers.Syslog
{
public class SyslogLogger
{
private readonly SyslogSettings _syslogSettings;
private readonly SyslogUdpSender _syslogUdpSender;
public SyslogLogger(SyslogSettings syslogSettings)
{
_syslogSettings = syslogSettings;
_syslogUdpSender = new SyslogUdpSender(syslogSettings.SyslogServerName, syslogSettings.SyslogServerPort);
}
public void Log(string message)
{
var syslogMessage = new SyslogMessage(
null,
(Facility)_syslogSettings.Facility,
Severity.Informational,
null,
_syslogSettings.Identity,
message);
_syslogUdpSender.Send(syslogMessage, new SyslogMessageSerializer());
}
private class SyslogMessageSerializer : SyslogMessageSerializerBase, ISyslogMessageSerializer
{
private const int AppNameMaxLength = 32;
public void Serialize(SyslogMessage message, Stream stream)
{
var priorityValue = CalculatePriorityValue(message.Facility, message.Severity);
string timestamp = null;
if (message.DateTimeOffset.HasValue)
{
var dt = message.DateTimeOffset.Value;
var day = dt.Day < 10 ? " " + dt.Day : dt.Day.ToString();
timestamp = string.Concat(dt.ToString("MMM "), day, dt.ToString(" HH:mm:ss"));
}
var headerBuilder = new StringBuilder();
headerBuilder.Append("<").Append(priorityValue).Append(">");
if (!string.IsNullOrEmpty(timestamp))
{
headerBuilder.Append(timestamp).Append(" ");
}
if (!string.IsNullOrEmpty(message.HostName))
{
headerBuilder.Append(message.HostName).Append(" ");
}
if (!message.Message.IsSiemOrientadTemplate())
{
var appName = message.AppName;
headerBuilder.Append(string.IsNullOrWhiteSpace(appName)
? appName
: (appName.Length > AppNameMaxLength ? appName.Substring(0, AppNameMaxLength) : appName) + ": ");
headerBuilder.Append(message.Message ?? "No Content");
}
var encoding = new UTF8Encoding(false);
var bytes = encoding.GetBytes(headerBuilder.ToString());
stream.Write(bytes, 0, bytes.Length);
}
}
}
}
e.g. of a message (I removed actual data and put on placeholders):
"LEEF:2.0|CompanyNameString|ProduceNameString|VersionString|int|^|
^cat=Test - QRADAR^sev=6^DescriptionString=^Timestamp=Apr 03 2017 14:48:02^userNameString=domain\DisplayName^accountName=samAccountName^proto=Syslog"
Any help will be much appreciated as it's been a while and I couldn't find a solution. Thanks in advance!

Finally found the issue.
I overlooked the fact that the content was in an "if" clause for non-SIEM systems.
Moving this line out of the clause resolve the issue for all syslog provider types.
headerBuilder.Append(message.Message ?? "No Content");

Related

Illegal character in path when running Azure function

I have an Azure function that has been working all day. About twenty minutes ago I started getting an error when trying to click the run button in Visual Studio. It successfully builds and then when it starts it displays and error the just states an 'illegal character in path - Visual Studio'. I've checked the git logs and no changes have been made so I'm unsure what's wrong.
I've attached a picture of the problem to try illustrate the issue:
I have tried everything I can think of. Here's a list of all the steps I've taken.
Restart machine
Re-cloned the repo
Re-installed Visual Studio 2017 & 2019
Deleted the appdata folder
Cleared Cache files
Browsed the debug menus
System restored
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Zupa.Products.ProductsService.Models.Messages.V1;
namespace Zupa.ProductFileUploadFunction
{
public static class FileUploadProcessor
{
private const string FunctionName = nameof(FileUploadProcessor);
[FunctionName(FunctionName)]
public static void Run(
[BlobTrigger("%IncomingContainerPath%/{blobFileName}", Connection = "AzureWebJobsStorage")]Stream inputBlob,
[ServiceBus("%QueueName%", Connection = "QueueServiceBus")]out string outgoingMessage,
string blobFileName, ILogger log)
{
log.LogInformation($"{FunctionName} Processing blob {Environment.NewLine} Name:{blobFileName + Environment.NewLine} Size: {inputBlob.Length} Bytes");
outgoingMessage = null;
var (parsedOrganisationId, parsedUploadId) = (Guid.Empty, Guid.Empty);
var organisationId = GetPartFromString(blobFileName, "/", 0);
var fileUploadType = GetPartFromString(blobFileName, "/", 1);
var isRecognisedFileUploadType = Enum.GetNames(typeof(FileUploadType)).Select(name => name.ToLowerInvariant()).Contains(fileUploadType.ToLowerInvariant());
var uploadId = GetPartFromString(blobFileName, "/", 2);
var fileName = GetPartFromString(blobFileName, "/", 3);
var propertyValidation = new Dictionary<string, bool>()
{
{
nameof(FileUploadDataEventMessage.OrganisationId),
string.IsNullOrEmpty(organisationId) || !Guid.TryParse(organisationId, out parsedOrganisationId)
},
{
nameof(FileUploadDataEventMessage.FileUploadType),
string.IsNullOrEmpty(fileUploadType) || isRecognisedFileUploadType
},
{
nameof(FileUploadDataEventMessage.UploadId),
string.IsNullOrEmpty(uploadId) || !Guid.TryParse(uploadId, out parsedUploadId)
},
{
nameof(FileUploadDataEventMessage.FileName),
string.IsNullOrEmpty(fileName)
}
};
foreach (KeyValuePair<string, bool> propertyValidationPair in propertyValidation)
LogPropertyInErrorState(log, propertyValidationPair.Value, blobFileName, propertyValidationPair.Key);
var hasInvalidPathParameters = parsedOrganisationId == Guid.Empty || !isRecognisedFileUploadType || parsedUploadId == Guid.Empty || string.IsNullOrEmpty(fileName);
outgoingMessage = !hasInvalidPathParameters ? JsonConvert.SerializeObject(new FileUploadDataEventMessage()
{
OrganisationId = parsedOrganisationId,
UploadId = parsedUploadId,
FileUploadType = Enum.Parse<FileUploadType>(PascalCaseWord(fileUploadType)),
FileName = fileName,
Timestamp = DateTimeOffset.Now
}) : null;
log.LogInformation($"{FunctionName} Processed blob {Environment.NewLine} Name:{blobFileName + Environment.NewLine} Size: {inputBlob.Length} Bytes");
}
private static string GetPartFromString(string inputString, string delimiter, int targetIndex)
{
var inputStringParts = inputString.Split(delimiter);
if (inputStringParts.ElementAtOrDefault(targetIndex) != null)
return inputStringParts[targetIndex];
return null;
}
private static void LogPropertyInErrorState(ILogger log, bool errorValidationCondition, string fileName, string propertyName)
{
var errorMessage = errorValidationCondition ?
$"{FunctionName} Failed to process blob {Environment.NewLine} Name: {fileName + Environment.NewLine} Missing or invalid {propertyName}" : string.Empty;
if (!string.IsNullOrEmpty(errorMessage))
log.LogInformation(errorMessage);
}
private static string PascalCaseWord(string input) =>
input.Substring(0, 1).ToUpperInvariant() + input.Substring(1);
}
}
It doesn't seem to be the issue with the function as the rest of the team doesn't seem to experience the same issue and can successfully run the function. So I'm assuming its a system issue.
For anyone experiencing this issue I have finally found a way to fix it
Thank you so much Tsuyoshi Ushio over on medium, follow the steps below to resolve the issue seems to be when the azure function tools files get in a bad state within the %appdata%/local folder
https://medium.com/#tsuyoshiushio/visual-studio-2017-2019-fails-when-i-create-an-azure-functions-project-89e993ef31f
You need to delete the following folder:
%localappdata%\AzureFunctionsTools

Raspberry Pi, Windows IoT, C#

I am currently experimenting with my Raspberry Pi with Grove sensors and Windows IoT. I am trying to transfer information from the Raspberry Pi to Azure and I receive an error (In line 85).
The code looks this way:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;
using Windows.ApplicationModel.Background;
using GrovePi;
using GrovePi.I2CDevices;
using GrovePi.Sensors;
using GrovePi.Common;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;
using Newtonsoft.Json;
// The Background Application template is documented at http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409
namespace GrooveTHS
{
public sealed class StartupTask : IBackgroundTask
{
IRgbLcdDisplay LCDDisplay;
public void Run(IBackgroundTaskInstance taskInstance)
{
IDHTTemperatureAndHumiditySensor sensor = DeviceFactory.Build.DHTTemperatureAndHumiditySensor(Pin.DigitalPin7, DHTModel.Dht11); // pinD7
LCDDisplay = DeviceFactory.Build.RgbLcdDisplay(); // pinI2C-1
IRotaryAngleSensor potentiometer = DeviceFactory.Build.RotaryAngleSensor(Pin.AnalogPin2); // pinA2
ILed red = DeviceFactory.Build.Led(Pin.DigitalPin5); // pinD5
ILed green = DeviceFactory.Build.Led(Pin.DigitalPin6); // pinD6
IUltrasonicRangerSensor dsensor = DeviceFactory.Build.UltraSonicSensor(Pin.DigitalPin4); // pin D4
double angle = 0;
double tmax = 0;
while (true)
{
Task.Delay(500).Wait();
angle = potentiometer.SensorValue();
sensor.Measure();
string sensortemp = sensor.TemperatureInCelsius.ToString();
tmax = Math.Floor(angle / 10);
string sensorvalue = dsensor.MeasureInCentimeters().ToString();
if (sensor.TemperatureInCelsius > tmax)
{
System.Diagnostics.Debug.WriteLine("Raumtemperatur: " + sensortemp + "C " + "Tmax: " + tmax.ToString() + "C");
red.AnalogWrite(Convert.ToByte(240));
green.AnalogWrite(Convert.ToByte(0));
}
else
{
System.Diagnostics.Debug.WriteLine("Raumtemperatur: " + sensortemp + "C" + "Tmax: " + tmax.ToString() + "C");
red.AnalogWrite(Convert.ToByte(0));
green.AnalogWrite(Convert.ToByte(240));
}
if (dsensor.MeasureInCentimeters() < 150)
{
LCDDisplay.SetBacklightRgb(BitConverter.GetBytes(990)[0], BitConverter.GetBytes(990)[0], BitConverter.GetBytes(990)[0]);
LCDDisplay.SetText("Raumtemperatur: " + sensortemp + "C " + "Tmax: " + tmax.ToString() + "C");
}
else
{
LCDDisplay.SetText("");
LCDDisplay.SetBacklightRgb(BitConverter.GetBytes(0)[0], BitConverter.GetBytes(0)[0], BitConverter.GetBytes(0)[0]);
}
}
}
static async void SendDeviceToCloudMessagesAsync(long inputDistance)
{
string iotHubUri = "IotHubAuburn.azure-devices.net"; // ! put in value !
string deviceId = "jb"; // ! put in value !
string deviceKey = "sHGJlQbLLMeMExNaqtvh8/7N7MHWlBZ0ESj2ePahSwQ="; // ! put in value !
DateTime time = DateTime.UtcNow;
var deviceClient = DeviceClient.Create(iotHubUri, AuthenticationMethodFactory.CreateAuthenticationWithRegistrySymmetricKey(deviceId, deviceKey), TransportType.Http1);
JSON jsonStr = new JSON();
jsonStr.distance = inputDistance;
jsonStr.time = time;
jsonStr.deviceId = deviceId;
var list = JsonConvert.SerializeObject(jsonStr);
System.Diagnostics.Debug.WriteLine(list);
var message = new Message(Encoding.UTF8.GetBytes(list));
await deviceClient.SendEventAsync(message);
}
}
}
And errors I am getting are following (Translated from german language):
1) CS0246 The type or a namespacename "JSON" was not found (maybe a
using-derective or a reprimand assembly is missing).
2) CS0246 The type or a namespacename "JSON" was not found (maybe a
using-derective or a reprimand assembly is missing).
Kind regards,
Alex
The error means that the "JSON" class definition can't be found.
As #Eric Magers pointed out, you can find from the code source you referenced where is the JSON class defined.
Or you can also define your own "JSON" class, for example, like this:
internal class JSON
{
public JSON()
{
}
public string deviceId { get; internal set; }
public long distance { get; internal set; }
public DateTime time { get; internal set; }
}
Another method without defining "JSON" class like this:
string dataBuffer;
DateTime time = DateTime.UtcNow;
long inputDistance = 0;
String deviceId = "MyCSharpDevice";
dataBuffer = string.Format("{{\"deviceId\":\"{0}\",\"distance\":{1},\"time\":{2}}}", deviceId, inputDistance, time);
Message message = new Message(Encoding.UTF8.GetBytes(dataBuffer));
await deviceClient.SendEventAsync(message);
For sending messages to Azure IoT Hub using HTTP protocol in C# you can reference this official sample. Note: the official sample is in Console Application and you are using a background application on Windows IoT Core. Application types are different but how to use Azure IoT Hub SDK is the same.

C#: How to write special characters to ADLDS?

I'm trying to write contacts into an ADLDS ldap for using them as a phone book for a Yealink T48G. Sometimes the name of the contact includes some special characters like "ö", "ß" and "é". If these characters are contained in the fields "givenName" or "displayName" neither the phone nor the ldap client can show them correctly and instead show some other chars (for example "ö" -> "ö"), however the "name" and "dn" fields show these characters correctly.
If I insert the contactvalues via ADSI-Edit or any other tool, the phone shows the name correctly, but my application is no longer able to read the inserted special chars from givenName and shows some questionmark-boxes, however the dn and name fields are read correctly.
I've already tried using utf-8, utf-16, utf-32, iso-8859-1 and windows-1252 as encoding for my application.
So the question is how can I store these special characters using C# in the givenName property for an inetOrgPerson in an ADLDS instance?
shown correctly:
shown incorrectly:
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices.Protocols;
using System.Net;
namespace LdapContacts
{
public class LdapClient
{
private LdapConnection connection;
public LdapClient(string host, int port, string distinguishedUsername, string password)
{
connection = new LdapConnection(new LdapDirectoryIdentifier(host, port));
connection.AuthType = AuthType.Basic;
connection.Credential = new NetworkCredential(distinguishedUsername, password);
connection.Bind();
}
public AddResponse SendAddRequest(string distinguishedName, List<DirectoryAttribute> attributes)
{
AddRequest request = new AddRequest(distinguishedName, attributes.ToArray());
return connection.SendRequest(request) as AddResponse;
}
public SearchResponse SendSearchRequest(string distinguishedName, string filter)
{
SearchRequest request = new SearchRequest();
request.DistinguishedName = distinguishedName;
request.Filter = filter;
request.Scope = SearchScope.Subtree;
return connection.SendRequest(request) as SearchResponse;
}
}
public class ContactsToLdap
{
private static void Main(string[] args)
{
LdapClient client = new LdapClient(Settings.LdapHost, Settings.LdapPort, Settings.LdapUsername, Settings.LdapPassword);
client.SendAddRequest("CN=Testöäüß,CN=Users,CN=testpart,DC=csdomain,DC=local", new List<DirectoryAttribute>()
{
new DirectoryAttribute("telephoneNumber", "0123456"),
new DirectoryAttribute("objectClass", "inetOrgPerson"),
new DirectoryAttribute("uid", "io3e"),
new DirectoryAttribute("givenName", "â é testnameöüÄß")
});
//distinguished name of contactsfolder
SearchResponse result = client.SendSearchRequest(Settings.LdapContactsFolder, "(objectClass=inetOrgPerson)");
foreach (SearchResultEntry sResult in result.Entries)
{
//display the index of the current entry
Console.Write((result.Entries.IndexOf(sResult) + 1) + ":\n");
foreach (DirectoryAttribute attribute in sResult.Attributes.Values)
{
//output the name of the attribute
Console.Write("\t" + attribute.Name + " = ");
for (int i = 0; i < attribute.Count; i++)
{
// convert the attribute to a string if it is an byte[]
// output if inserted with ADSI-Edit: ? ? testname????
// output if inserted with this code: â é testnameöüÄß
if (attribute[i].GetType().Equals(typeof(byte[])))
{
Console.Write(Encoding.UTF8.GetString((byte[])attribute[i]) + "; ");
}
else
{
Console.Write(attribute[i] + "; ");
}
}
Console.WriteLine();
}
Console.WriteLine();
}
}
}
}
The issue was resolved by setting the protocolversion that should be used to version 3.
connection = new LdapConnection(new LdapDirectoryIdentifier(host, port));
connection.SessionOptions.ProtocolVersion = 3;

Exception: Acess Violation in client C#

I am trying to learn C# through trials and errors. I have a server in Python, and the client in C#.
The client is supposed to get data from the server, save it to disk ((which it doesn't)), then continue using that data to communicate until the user decides to exit it.
Unfortunately, it has been raising an Exception Access Violation for quite some time, and provides no helpful information as to why.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Scripting.Hosting;
using System.Threading;
using Rage;
using System.Net.Sockets;
using System.IO;
[assembly: Rage.Attributes.Plugin("LSPDFROnlineClient", Description = "LSPDFR Online Client. Used to connect to LSPDFR Online.", Author = "Thecheater887")]
namespace LSPDFROnlineClient
{
public class EntryPoint
{
private static int IsDead;
public static void Main()
{
IsDead = 0;
Thread mt = new Thread(new ThreadStart(Run));
mt.Start();
while (true)
{
if (IsDead == 1)
{
break;
}
GameFiber.Yield();
}
return;
}
public static void Run()
{
File.WriteAllText("C:/ProgramData/dbg.log","1");
try
{
Byte[] header;
Byte[] packet;
Byte[] data;
Byte[] kad;
Byte[] td;
int paylen;
String rd;
String nd;
String msgid;
File.WriteAllText("C:/ProgramData/dbg.log", "2");
TcpClient connector = new TcpClient();
connector.Connect("127.0.0.1", 5773);
NetworkStream conn = connector.GetStream();
try {
File.WriteAllText("C:/ProgramData/dbg.log", "3");
FileStream savedat = File.OpenRead("C:/Users/Public/Documents/save.dat");
BinaryReader savdat = new BinaryReader(savedat);
nd = savdat.ReadString();
savdat.Close();
if (nd.Length == 16)
{
} else {
File.WriteAllText("C:/ProgramData/save.dat", "user000000000000");
nd = "user000000000000";
}
}
catch
{
File.WriteAllText("C:/ProgramData/save.dat", "user000000000000");
nd = "user000000000000";
}
File.WriteAllText("C:/ProgramData/dbg.log", "4");
data = new Byte[26];
data = Encoding.ASCII.GetBytes("clogr00000" + nd);
conn.Write(data, 0, data.Length);
while (true)
{
try
{
// Get header of packet
header = new Byte[26];
Int32 rcvhead = conn.Read(header, 0, header.Length);
String hd = Encoding.ASCII.GetString(header, 0, rcvhead);
//Deal with it 8-)
msgid = hd.Substring(0, 5);
paylen = Convert.ToInt32(hd.Substring(5, 5));
string servkey = hd.Substring(10, 16);
}
catch
{
continue;
}
File.WriteAllText("C:/ProgramData/dbg.log", "5");
try
{
//Receive packet data
if (paylen > 0)
{
packet = new Byte[paylen];
Int32 newdata = conn.Read(packet, 0, packet.Length);
rd = Encoding.ASCII.GetString(packet, 0, newdata);
}
else
{
rd = null;
}
File.WriteAllText("C:/ProgramData/dbg.log", "6");
if (msgid == "ConOK")
{
File.WriteAllText("C:/ProgramData/dbg.log", "7");
string userid = rd.Substring(0, 16);
Game.DisplayHelp(rd.Substring(16, (rd.Length - 16)));
File.WriteAllText("C:/ProgramData/save.dat", userid);
File.WriteAllText("C:/ProgramData/dbg.log", "8");
}
else if (msgid == "savdt")
{
File.WriteAllText("C:/ProgramData/dbg.log", "9");
string[] tnd = rd.Split(',');
var nud = new List<string>();
nud.Add("Player1");
nud.AddRange(tnd);
File.WriteAllText("C:/ProgramData/dbg.log", "A");
string name = nud[0];
string streetname = nud[1];
int money = Convert.ToInt32(nud[2]);
int bounty = Convert.ToInt32(nud[3]);
int playerrep = Convert.ToInt32(nud[4]);
File.WriteAllText("C:/ProgramData/dbg.log", "B");
int rep = Convert.ToInt32(nud[5]);
string pclass = nud[6];
bool canbecop = Convert.ToBoolean(nud[7]);
int rank = Convert.ToInt32(nud[8]);
int stars = Convert.ToInt32(nud[9]);
int cites = Convert.ToInt32(nud[10]);
File.WriteAllText("C:/ProgramData/dbg.log", "C");
int citesgiven = Convert.ToInt32(nud[11]);
int citesdismissed = Convert.ToInt32(nud[12]);
int arrestsmade = Convert.ToInt32(nud[13]);
int arrested = Convert.ToInt32(nud[14]);
int convictionsmade = Convert.ToInt32(nud[15]);
int convitced = Convert.ToInt32(nud[16]);
string warrant = nud[17];
File.WriteAllText("C:/ProgramData/dbg.log", "D");
int prisontimeremaining = Convert.ToInt32(nud[18]);
int copskilled = Convert.ToInt32(nud[19]);
int crimskilled = Convert.ToInt32(nud[20]);
int civskilled = Convert.ToInt32(nud[21]);
int bountyclaimed = Convert.ToInt32(nud[22]);
int overflowprep = Convert.ToInt32(nud[23]);
string title = nud[24];
bool banned = Convert.ToBoolean(nud[25]);
bool vip = Convert.ToBoolean(nud[26]);
int viprank = Convert.ToInt32(nud[27]);
File.WriteAllText("C:/ProgramData/dbg.log", "E");
var v3 = new Vector3();
float posx = Convert.ToSingle(nud[29]);
float posy = Convert.ToSingle(nud[30]);
float posz = Convert.ToSingle(nud[31]);
v3.X = posx;
v3.Y = posy;
v3.Z = posz;
File.WriteAllText("C:/ProgramData/dbg.log", "EE");
int rot = Convert.ToInt32(nud[32]);
File.WriteAllText("C:/ProgramData/dbg.log", "FF");
World.TeleportLocalPlayer(v3, false);
File.WriteAllText("C:/ProgramData/dbg.log", "F");
string custommessage = nud[28];
if (custommessage == "null")
{
} else {
Game.DisplayNotification(custommessage);
}
}
else if (msgid == "isalv")
{
kad = new Byte[26];
kad = Encoding.ASCII.GetBytes("yesil00000" + nd);
conn.Write(kad, 0, kad.Length);
}
else if (msgid == "pospk")
{
}
else
{
Game.DisplayNotification("Unknown packet recieved! ID: " + msgid);
}
//send end client turn
td = new Byte[26];
td = Encoding.ASCII.GetBytes("endmt00000" + nd);
conn.Write(td, 0,td.Length);
File.WriteAllText("C:/ProgramData/dbg.log", "0");
//
}
catch (Exception e)
{
Game.DisplayHelp(Convert.ToString(e));
Game.DisplayNotification("LSPDFR Online has crashed. Try reloading it maybe..?");
}
}
} catch (Exception e) {
Game.DisplayHelp(Convert.ToString(e));
Game.DisplayNotification("Connection interrupted! Reconnecting....");
IsDead = 1;
return;
}
}
}
}
The protocol goes as such;
Client -> Server: LoginRequest
Server -> Client: LoginOkay
Client -> Server: EndTurnMessage
Server -> Client: SaveDataMessage
Client -> Server: EndTurnMessage
Server -> Client: PositionUpdatePacket
Client -> Server: EndTurnMessage
Then continue routine, however, the server only receives one of these EndTurnMessage packets, which means it is choking on the save data portion, right?
Possibly, but that was working at an earlier time without flaw, and hasn't been modified since.
It is a class file, so it can't be debugged, and I've been tearing my hair out as to what is causing it.
Yes, it is crap-code, and needs rewritten at some point, I am aware, but I'd like it to work before I rewrite it entirely.
TL;DR: Why is this code raising an Access Violation? It's around the savdt sector or after.
UPDATE: I fixed the issue posted in the first answer, however, that didn't do much, so, as posted in both the answer and comments, it's rather difficult to debug with a program, so I'll try the old fashioned route of logging info every so many lines of code. I'll keep this updated.
UPDATE 2: I have figured out from the log debugging, that the line causing the error is World.TeleportLocalPlayer(v3, false);. Unfortunatley, World can't be inherited, and the documentation claims that Vector3 requires you to set it's internal values using get and set. I saw that on MSDN previously, but have no clue about how to search it, and there is nor get or set methods available within that Vector3 object.
You might have a stream that remained open, which prevents a new one to be created. If the msgid is "ConOK" you are creating a new instance without closing it after the write operation is done.
if (msgid == "ConOK"){
string userid = rd.Substring(0, 16);
Game.DisplayHelp(rd.Substring(16, (rd.Length - 16)));
FileStream savedat = File.OpenWrite(("C:/ProgramData/save.dat"));
BinaryWriter savdat = new BinaryWriter(savedat);
savdat.Write(userid);
// Close file stream here
}
But that's just a first guess. You can help us and yourself by making use of the debugger. The fact that your code is contained by a "class file" is no problem but a requirement.
Hava a look at this article for more information about debugging in the world of C#:
http://www.dotnetperls.com/debugging
At a first glance, you can have different class of bugs. Disregarding the logic flows and intended behaviour of the program, let's start with basic debugging.
at this step, don't use threads and fibers, from Main just call Run
there isn't strong input validation
use a lot more of try catch, isolating small pieces of code
in the catch, print ex.Message and ex.StackTrace
read carefully the docs about the methods you call and their possible exceptions
it is weird you write a file inside a exception (catch)
possible race conditions on global variables?
inside Run to set IsDead use Interlocked.Increment
https://msdn.microsoft.com/en-us/library/dd78zt0c(v=vs.110).aspx
...
remove the unused ( I think like Microsoft.Scripting.Hosting ), it only confuse-a-cat

OpenXml Excel: throw error in any word after mail address

I read Excel files using OpenXml. all work fine but if the spreadsheet contains one cell that has an address mail and after it a space and another word, such as:
abc#abc.com abc
It throws an exception immediately at the opening of the spreadsheet:
var _doc = SpreadsheetDocument.Open(_filePath, false);
exception:
DocumentFormat.OpenXml.Packaging.OpenXmlPackageException
Additional information:
Invalid Hyperlink: Malformed URI is embedded as a
hyperlink in the document.
There is an open issue on the OpenXml forum related to this problem: Malformed Hyperlink causes exception
In the post they talk about encountering this issue with a malformed "mailto:" hyperlink within a Word document.
They propose a work-around here: Workaround for malformed hyperlink exception
The workaround is essentially a small console application which locates the invalid URL and replaces it with a hard-coded value; here is the code snippet from their sample that does the replacement; you could augment this code to attempt to correct the passed brokenUri:
private static Uri FixUri(string brokenUri)
{
return new Uri("http://broken-link/");
}
The problem I had was actually with an Excel document (like you) and it had to do with a malformed http URL; I was pleasantly surprised to find that their code worked just fine with my Excel file.
Here is the entire work-around source code, just in case one of these links goes away in the future:
void Main(string[] args)
{
var fileName = #"C:\temp\corrupt.xlsx";
var newFileName = #"c:\temp\Fixed.xlsx";
var newFileInfo = new FileInfo(newFileName);
if (newFileInfo.Exists)
newFileInfo.Delete();
File.Copy(fileName, newFileName);
WordprocessingDocument wDoc;
try
{
using (wDoc = WordprocessingDocument.Open(newFileName, true))
{
ProcessDocument(wDoc);
}
}
catch (OpenXmlPackageException e)
{
e.Dump();
if (e.ToString().Contains("The specified package is not valid."))
{
using (FileStream fs = new FileStream(newFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
UriFixer.FixInvalidUri(fs, brokenUri => FixUri(brokenUri));
}
}
}
}
private static Uri FixUri(string brokenUri)
{
brokenUri.Dump();
return new Uri("http://broken-link/");
}
private static void ProcessDocument(WordprocessingDocument wDoc)
{
var elementCount = wDoc.MainDocumentPart.Document.Descendants().Count();
Console.WriteLine(elementCount);
}
}
public static class UriFixer
{
public static void FixInvalidUri(Stream fs, Func<string, Uri> invalidUriHandler)
{
XNamespace relNs = "http://schemas.openxmlformats.org/package/2006/relationships";
using (ZipArchive za = new ZipArchive(fs, ZipArchiveMode.Update))
{
foreach (var entry in za.Entries.ToList())
{
if (!entry.Name.EndsWith(".rels"))
continue;
bool replaceEntry = false;
XDocument entryXDoc = null;
using (var entryStream = entry.Open())
{
try
{
entryXDoc = XDocument.Load(entryStream);
if (entryXDoc.Root != null && entryXDoc.Root.Name.Namespace == relNs)
{
var urisToCheck = entryXDoc
.Descendants(relNs + "Relationship")
.Where(r => r.Attribute("TargetMode") != null && (string)r.Attribute("TargetMode") == "External");
foreach (var rel in urisToCheck)
{
var target = (string)rel.Attribute("Target");
if (target != null)
{
try
{
Uri uri = new Uri(target);
}
catch (UriFormatException)
{
Uri newUri = invalidUriHandler(target);
rel.Attribute("Target").Value = newUri.ToString();
replaceEntry = true;
}
}
}
}
}
catch (XmlException)
{
continue;
}
}
if (replaceEntry)
{
var fullName = entry.FullName;
entry.Delete();
var newEntry = za.CreateEntry(fullName);
using (StreamWriter writer = new StreamWriter(newEntry.Open()))
using (XmlWriter xmlWriter = XmlWriter.Create(writer))
{
entryXDoc.WriteTo(xmlWriter);
}
}
}
}
}
The fix by #RMD works great. I've been using it for years. But there is a new fix.
You can see the fix here in the changelog for issue #793
Upgrade OpenXML to 2.12.0.
Right click solution and select Manage NuGet Packages.
Implement the fix
It is helpful to have a unit test. Create an excel file with a bad email address like test#gmail,com. (Note the comma instead of the dot).
Make sure the stream you open and the call to SpreadsheetDocument.Open allows Read AND Write.
You need to implement a RelationshipErrorHandlerFactory and use it in the options when you open. Here is the code I used:
public class UriRelationshipErrorHandler : RelationshipErrorHandler
{
public override string Rewrite(Uri partUri, string id, string uri)
{
return "https://broken-link";
}
}
Then you need to use it when you open the document like this:
var openSettings = new OpenSettings
{
RelationshipErrorHandlerFactory = package =>
{
return new UriRelationshipErrorHandler();
}
};
using var document = SpreadsheetDocument.Open(stream, true, openSettings);
One of the nice things about this solution is that it does not require you to create a temporary "fixed" version of your file and it is far less code.
Unfortunately solution where you have to open file as zip and replace broken hyperlink would not help me.
I just was wondering how it is posible that it works fine when your target framework is 4.0 even if your only installed .Net Framework has version 4.7.2.
I have found out that there is private static field inside System.UriParser that selects version of URI's RFC specification. So it is possible to set it to V2 as it is set for .net 4.0 and lower versions of .Net Framework. Only problem that it is private static readonly.
Maybe someone will want to set it globally for whole application. But I wrote UriQuirksVersionPatcher that will update this version and restore it back in Dispose method. It is obviously not thread-safe but it is acceptable for my purpose.
using System;
using System.Diagnostics;
using System.Reflection;
namespace BarCap.RiskServices.RateSubmissions.Utility
{
#if (NET20 || NET35 || NET40)
public class UriQuirksVersionPatcher : IDisposable
{
public void Dispose()
{
}
}
#else
public class UriQuirksVersionPatcher : IDisposable
{
private const string _quirksVersionFieldName = "s_QuirksVersion"; //See Source\ndp\fx\src\net\System\_UriSyntax.cs in NexFX sources
private const string _uriQuirksVersionEnumName = "UriQuirksVersion";
/// <code>
/// private enum UriQuirksVersion
/// {
/// V1 = 1, // RFC 1738 - Not supported
/// V2 = 2, // RFC 2396
/// V3 = 3, // RFC 3986, 3987
/// }
/// </code>
private const string _oldQuirksVersion = "V2";
private static readonly Lazy<FieldInfo> _targetFieldInfo;
private static readonly Lazy<int?> _patchValue;
private readonly int _oldValue;
private readonly bool _isEnabled;
static UriQuirksVersionPatcher()
{
var targetType = typeof(UriParser);
_targetFieldInfo = new Lazy<FieldInfo>(() => targetType.GetField(_quirksVersionFieldName, BindingFlags.Static | BindingFlags.NonPublic));
_patchValue = new Lazy<int?>(() => GetUriQuirksVersion(targetType));
}
public UriQuirksVersionPatcher()
{
int? patchValue = _patchValue.Value;
_isEnabled = patchValue.HasValue;
if (!_isEnabled) //Disabled if it failed to get enum value
{
return;
}
int originalValue = QuirksVersion;
_isEnabled = originalValue != patchValue;
if (!_isEnabled) //Disabled if value is proper
{
return;
}
_oldValue = originalValue;
QuirksVersion = patchValue.Value;
}
private int QuirksVersion
{
get
{
return (int)_targetFieldInfo.Value.GetValue(null);
}
set
{
_targetFieldInfo.Value.SetValue(null, value);
}
}
private static int? GetUriQuirksVersion(Type targetType)
{
int? result = null;
try
{
result = (int)targetType.GetNestedType(_uriQuirksVersionEnumName, BindingFlags.Static | BindingFlags.NonPublic)
.GetField(_oldQuirksVersion, BindingFlags.Static | BindingFlags.Public)
.GetValue(null);
}
catch
{
#if DEBUG
Debug.WriteLine("ERROR: Failed to find UriQuirksVersion.V2 enum member.");
throw;
#endif
}
return result;
}
public void Dispose()
{
if (_isEnabled)
{
QuirksVersion = _oldValue;
}
}
}
#endif
}
Usage:
using(new UriQuirksVersionPatcher())
{
using(var document = SpreadsheetDocument.Open(fullPath, false))
{
//.....
}
}
P.S. Later I found that someone already implemented this pathcher: https://github.com/google/google-api-dotnet-client/blob/master/Src/Support/Google.Apis.Core/Util/UriPatcher.cs
I haven't use OpenXml but if there's no specific reason for using it then I highly recommend LinqToExcel from LinqToExcel. Example of code is here:
var sheet = new ExcelQueryFactory("filePath");
var allRows = from r in sheet.Worksheet() select r;
foreach (var r in allRows) {
var cella = r["Header"].ToString();
}

Categories

Resources