public void HandleMessage(byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { FlagMessageType messageType = (FlagMessageType)mr.Read<int>(); switch (messageType) { case FlagMessageType.LIST: { //List code string[] serverFlagFiles = mr.Read<string[]>(); string[] serverFlagOwners = mr.Read<string[]>(); string[] serverFlagShaSums = mr.Read<string[]>(); for (int i = 0; i < serverFlagFiles.Length; i++) { FlagInfo fi = new FlagInfo(); fi.owner = serverFlagOwners[i]; fi.shaSum = serverFlagShaSums[i]; serverFlags[Path.GetFileNameWithoutExtension(serverFlagFiles[i])] = fi; } syncComplete = true; //Check if we need to upload the flag flagChangeEvent = true; } break; case FlagMessageType.FLAG_DATA: { FlagRespondMessage frm = new FlagRespondMessage(); frm.flagInfo.owner = mr.Read<string>(); frm.flagName = mr.Read<string>(); frm.flagData = mr.Read<byte[]>(); frm.flagInfo.shaSum = Common.CalculateSHA256Hash(frm.flagData); newFlags.Enqueue(frm); } break; case FlagMessageType.DELETE_FILE: { string flagName = mr.Read<string>(); string flagFile = Path.Combine(flagPath, flagName); if (File.Exists(flagFile)) { try { if (File.Exists(flagFile)) { DarkLog.Debug("Deleting flag " + flagFile); File.Delete(flagFile); } } catch (Exception e) { DarkLog.Debug("Error deleting flag " + flagFile + ", exception: " + e); } } } break; } } }
public static void HandleSplitMessage(ClientObject client, byte[] messageData) { if (!client.isReceivingSplitMessage) { //New split message using (MessageReader mr = new MessageReader(messageData)) { client.receiveSplitMessage = new ClientMessage(); client.receiveSplitMessage.type = (ClientMessageType)mr.Read<int>(); client.receiveSplitMessage.data = new byte[mr.Read<int>()]; client.receiveSplitMessageBytesLeft = client.receiveSplitMessage.data.Length; byte[] firstSplitData = mr.Read<byte[]>(); firstSplitData.CopyTo(client.receiveSplitMessage.data, 0); client.receiveSplitMessageBytesLeft -= firstSplitData.Length; } client.isReceivingSplitMessage = true; } else { //Continued split message messageData.CopyTo(client.receiveSplitMessage.data, client.receiveSplitMessage.data.Length - client.receiveSplitMessageBytesLeft); client.receiveSplitMessageBytesLeft -= messageData.Length; } if (client.receiveSplitMessageBytesLeft == 0) { ClientHandler.HandleMessage(client, client.receiveSplitMessage); client.receiveSplitMessage = null; client.isReceivingSplitMessage = false; } }
public void HandleAdminMessage(byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { AdminMessageType messageType = (AdminMessageType)mr.Read<int>(); switch (messageType) { case AdminMessageType.LIST: { string[] adminNames = mr.Read<string[]>(); foreach (string adminName in adminNames) { RegisterServerAdmin(adminName); } } break; case AdminMessageType.ADD: { string adminName = mr.Read<string>(); RegisterServerAdmin(adminName); } break; case AdminMessageType.REMOVE: { string adminName = mr.Read<string>(); UnregisterServerAdmin(adminName); } break; } } }
static UnknownFieldCollection ReadGroup(MessageTag startTag, MessageReader reader) { var group = new UnknownFieldCollection(); for(int stop = startTag.WithWireType(WireType.EndGroup), tag = reader.ReadInt32(); tag != stop; tag = reader.ReadInt32()) group.Add(new MessageTag(tag), reader); return group; }
public static void HandleVesselsRequest(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { int sendVesselCount = 0; int cachedVesselCount = 0; List<string> clientRequested = new List<string>(mr.Read<string[]>()); lock (Server.universeSizeLock) { foreach (string file in Directory.GetFiles(Path.Combine(Server.universeDirectory, "Vessels"))) { string vesselID = Path.GetFileNameWithoutExtension(file); byte[] vesselData = File.ReadAllBytes(file); string vesselObject = Common.CalculateSHA256Hash(vesselData); if (clientRequested.Contains(vesselObject)) { sendVesselCount++; VesselProto.SendVessel(client, vesselID, vesselData); } else { cachedVesselCount++; } } } DarkLog.Debug("Sending " + client.playerName + " " + sendVesselCount + " vessels, cached: " + cachedVesselCount + "..."); SendVesselsComplete(client); } }
public static void HandlePlayerColor(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { PlayerColorMessageType messageType = (PlayerColorMessageType)mr.Read<int>(); switch (messageType) { case PlayerColorMessageType.SET: { string playerName = mr.Read<string>(); if (playerName != client.playerName) { DarkLog.Debug(client.playerName + " tried to send a color update for " + playerName + ", kicking."); Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending a color update for another player"); return; } client.playerColor = mr.Read<float[]>(); //Relay the message ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.PLAYER_COLOR; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, true); } break; } } }
public static void HandleVesselRemoval(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { //Don't care about the subspace on the server. mr.Read<double>(); string vesselID = mr.Read<string>(); bool isDockingUpdate = mr.Read<bool>(); if (!isDockingUpdate) { DarkLog.Debug("Removing vessel " + vesselID + " from " + client.playerName); } else { DarkLog.Debug("Removing DOCKED vessel " + vesselID + " from " + client.playerName); } if (File.Exists(Path.Combine(Server.universeDirectory, "Vessels", vesselID + ".txt"))) { lock (Server.universeSizeLock) { File.Delete(Path.Combine(Server.universeDirectory, "Vessels", vesselID + ".txt")); } } //Relay the message. ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.VESSEL_REMOVE; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, false); } }
internal static void PrintMessage(Message msg) { Console.WriteLine ("Message (" + msg.Header.Endianness + " endian, v" + msg.Header.MajorVersion + "):"); Console.WriteLine (indent + "Type: " + msg.Header.MessageType); Console.WriteLine (indent + "Flags: " + msg.Header.Flags); Console.WriteLine (indent + "Serial: " + msg.Header.Serial); //foreach (HeaderField hf in msg.HeaderFields) // Console.WriteLine (indent + hf.Code + ": " + hf.Value); Console.WriteLine (indent + "Header Fields:"); foreach (KeyValuePair<FieldCode,object> field in msg.Header.Fields) Console.WriteLine (indent + indent + field.Key + ": " + field.Value); Console.WriteLine (indent + "Body (" + msg.Header.Length + " bytes):"); if (msg.Body != null) { MessageReader reader = new MessageReader (msg); //TODO: this needs to be done more intelligently //TODO: number the args try { foreach (DType dtype in msg.Signature.GetBuffer ()) { if (dtype == DType.Invalid) continue; object arg = reader.ReadValue (dtype); Console.WriteLine (indent + indent + dtype + ": " + arg); } } catch { Console.WriteLine (indent + indent + "monitor is too dumb to decode message body"); } } }
public async Task<Response> ExecuteRequest(Request request) { if (!_tcpClient.Connected) { throw new InvalidOperationException("Connect first."); } var converter = new MessageConverter(); var requestBuffer = new MemoryStream(); var streamWriter = new HmBinaryMessageWriter(requestBuffer); var requestReader = new MessageReader(request); converter.Convert(requestReader, streamWriter); var networkStream = _tcpClient.GetStream(); requestBuffer.Position = 0; await requestBuffer.CopyToAsync(networkStream); await Task.Delay(100); //todo: implement buffered reader var streamReader = new HmBinaryMessageReader(networkStream); var responseBuilder = new MessageBuilder(); converter.Convert(streamReader, responseBuilder); var response = (Response)responseBuilder.Result; return response; }
public static void HandleWarpControl(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { WarpMessageType warpType = (WarpMessageType)mr.Read<int>(); switch (warpType) { case WarpMessageType.REQUEST_CONTROLLER: { HandleRequestController(client); } break; case WarpMessageType.RELEASE_CONTROLLER: { HandleReleaseController(client); } break; case WarpMessageType.REPLY_VOTE: { bool voteReply = mr.Read<bool>(); HandleReplyVote(client, voteReply); } break; case WarpMessageType.NEW_SUBSPACE: { long serverTime = mr.Read<long>(); double planetTime = mr.Read<double>(); float subspaceRate = mr.Read<float>(); HandleNewSubspace(client, serverTime, planetTime, subspaceRate); } break; case WarpMessageType.CHANGE_SUBSPACE: { int newSubspace = mr.Read<int>(); HandleChangeSubspace(client, newSubspace); } break; case WarpMessageType.REPORT_RATE: { float newSubspaceRate = mr.Read<float>(); HandleReportRate(client, newSubspaceRate); } break; case WarpMessageType.CHANGE_WARP: { bool physWarp = mr.Read<bool>(); int rateIndex = mr.Read<int>(); long serverClock = mr.Read<long>(); double planetTime = mr.Read<double>(); HandleChangeWarp(client, physWarp, rateIndex, serverClock, planetTime); } break; #if DEBUG default: throw new NotImplementedException("Warp type not implemented"); #endif } } }
public object ToType (Type conversionType, IFormatProvider provider) { Signature typeSig = Signature.GetSig (conversionType); if (typeSig != signature) throw new InvalidCastException (); MessageReader reader = new MessageReader (endianness, data); return reader.ReadValue (conversionType); }
/// <summary> /// Reads the <see cref="OwnHomeDataMessage"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="OwnHomeDataMessage"/>. /// </param> public override void ReadMessage(MessageReader reader) { LastVisit = TimeSpan.FromSeconds(reader.ReadInt32()); Unknown1 = reader.ReadInt32(); // -1 Timestamp = DateTimeConverter.FromUnixTimestamp(reader.ReadInt32()); OwnAvatarData = new AvatarData(); OwnAvatarData.Read(reader); }
/// <summary> /// Reads the <see cref="MoveVillageObjectCommand"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="MoveVillageObjectCommand"/>. /// </param> public override void ReadCommand(MessageReader reader) { MoveData = new MoveVillageObjectData(); MoveData.X = reader.ReadInt32(); MoveData.Y = reader.ReadInt32(); MoveData.VillageObjectGameIndex = reader.ReadInt32(); Unknown1 = reader.ReadInt32(); }
public static void HandleConnectionEnd(ClientObject client, byte[] messageData) { string reason = "Unknown"; using (MessageReader mr = new MessageReader(messageData)) { reason = mr.Read<string>(); } DarkLog.Debug(client.playerName + " sent connection end message, reason: " + reason); ClientHandler.DisconnectClient(client); }
/// <summary> /// Reads the <see cref="ClearObstacleCommand"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="ClearObstacleCommand"/>. /// </param> public override void ReadCommand(MessageReader reader) { var gameID = reader.ReadInt32(); if (!Obstacle.ValidGameID(gameID)) throw new InvalidCommandException("Unexpected game ID: " + gameID, this); ObstacleGameIndex = Obstacle.GameIDToIndex(gameID); Unknown1 = reader.ReadInt32(); }
public void Setup() { var pages = new MemoryPageReaderWriter(); var checkpoint = new MemoryCheckpointReaderWriter(); Writer = new MessageWriter(pages, checkpoint); Reader = new MessageReader(checkpoint, pages); CheckpointReader = checkpoint; PageWriter = pages; Writer.Init(); }
public static UnknownField Create(MessageTag tag, MessageReader reader) { switch(tag.WireType) { case WireType.Fixed64: return new UnknownFieldFixed64(tag, reader); case WireType.String: return new UnknownFieldString(tag, reader); case WireType.StartGroup: return new UnknownFieldGroup(tag, reader); case WireType.Fixed32: return new UnknownFieldFixed32(tag, reader); } return new UnknownFieldVarint(tag, reader.ReadInt64()); }
/// <summary> /// Reads the <see cref="NewClientEncryptionMessage"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="NewClientEncryptionMessage"/>. /// </param> public override void ReadMessage(MessageReader reader) { Unknown1 = reader.ReadInt32(); Unknown2 = reader.ReadInt32(); MajorVersion = reader.ReadInt32(); Unknown4 = reader.ReadInt32(); MinorVersion = reader.ReadInt32(); Hash = reader.ReadString(); Unknown6 = reader.ReadInt32(); Unknown7 = reader.ReadInt32(); }
/// <summary> /// Constructor for ClientConnection /// </summary> /// <param name="id">ClientID is an id representing this connection</param> /// <param name="connection">This is a TCPConnection representing the connection to the client</param> /// <param name="MessageReceived">This is a delegate representing the method to be called when a message is received</param> /// <param name="ConnectionFailed">This is a delegate representing the method to be called when the connection fails</param> /// <param name="MessageFailed">This is a delegate representing the method to be called when a corrupt message is received</param> public ClientConnection(TCPConnection connection) { this.buffer = new Buffer<AbstractMessage>(); this.connection = connection; ClientID = new ClientID(); terminating = false; hasStarted = false; writer = new MessageWriter(this, connection); reader = new MessageReader(this, connection); }
/// <summary> /// Reads the <see cref="UpgradeBuildingCommand"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="UpgradeBuildingCommand"/>. /// </param> public override void ReadCommand(MessageReader reader) { var gameID = reader.ReadInt32(); if (!Building.ValidGameID(gameID)) throw new InvalidCommandException("Unexpected data ID: " + gameID, this); BuildingGameIndex = Building.GameIDToIndex(gameID); Unknown1 = reader.ReadByte(); Unknown2 = reader.ReadInt32(); }
static void Main(string[] args) { using (var messageReader = new MessageReader()) { var routingKey = "hello"; if (args.Length > 0) { routingKey = args[0]; } messageReader.ConsumeMessages(routingKey); } }
/// <summary> /// Reads the <see cref="BuyDecoration"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="BuyDecoration"/>. /// </param> public override void ReadCommand(MessageReader reader) { //X = reader.ReadInt32(); //Y = reader.ReadInt32(); //var dataID = reader.ReadInt32(); //if (!Building.ValidDataID(dataID)) // throw new InvalidCommandException("Unexpected data ID: " + dataID, this); //BuildingDataIndex = Building.DataIDToIndex(dataID); //Unknown1 = reader.ReadInt32(); }
public static void HandleModDataMessage(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { string modName = mr.Read<string>(); bool relay = mr.Read<bool>(); bool highPriority = mr.Read<bool>(); byte[] modData = mr.Read<byte[]>(); if (relay) { DMPModInterface.SendDMPModMessageToAll(client, modName, modData, highPriority); } DMPModInterface.OnModMessageReceived(client, modName, modData); } }
public void Should_republish_all_error_messages_in_the_given_directory() { var parameters = new QueueParameters { HostName = "localhost", Username = "******", Password = "******", MessageFilePath = @"C:\temp\MessageOutput" }; var rawErrorMessages = new MessageReader() .ReadMessages(parameters, DefaultConsumerErrorStrategy.EasyNetQErrorQueue); errorRetry.RetryErrors(rawErrorMessages, parameters); }
public static void HandleScenarioModuleData(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { //Don't care about subspace / send time. string[] scenarioName = mr.Read<string[]>(); DarkLog.Debug("Saving " + scenarioName.Length + " scenario modules from " + client.playerName); for (int i = 0; i < scenarioName.Length; i++) { byte[] scenarioData = Compression.DecompressIfNeeded(mr.Read<byte[]>()); File.WriteAllBytes(Path.Combine(Server.universeDirectory, "Scenarios", client.playerName, scenarioName[i] + ".txt"), scenarioData); } } }
public void Should_republish_all_error_messages_in_the_given_directory() { var parameters = new QueueParameters { HostName = "localhost", Username = "******", Password = "******", MessageFilePath = @"C:\temp\MessageOutput" }; var rawErrorMessages = new MessageReader() .ReadMessages(parameters, conventions.ErrorQueueNamingConvention()); errorRetry.RetryErrors(rawErrorMessages, parameters); }
public void HandleLockMessage(byte[] messageData) { lock (lockObject) { using (MessageReader mr = new MessageReader(messageData, false)) { LockMessageType lockMessageType = (LockMessageType)mr.Read<int>(); switch (lockMessageType) { case LockMessageType.LIST: { //We shouldn't need to clear this as LIST is only sent once, but better safe than sorry. serverLocks.Clear(); string[] lockKeys = mr.Read<string[]>(); string[] lockValues = mr.Read<string[]>(); for (int i = 0; i < lockKeys.Length; i++) { serverLocks.Add(lockKeys[i], lockValues[i]); } } break; case LockMessageType.ACQUIRE: { string playerName = mr.Read<string>(); string lockName = mr.Read<string>(); bool lockResult = mr.Read<bool>(); if (lockResult) { serverLocks[lockName] = playerName; } FireAcquireEvent(playerName, lockName, lockResult); } break; case LockMessageType.RELEASE: { string playerName = mr.Read<string>(); string lockName = mr.Read<string>(); if (serverLocks.ContainsKey(lockName)) { serverLocks.Remove(lockName); } FireReleaseEvent(playerName, lockName); } break; } } } }
/// <summary> /// Reads the <see cref="ChatMessageServerMessage"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="ChatMessageServerMessage"/>. /// </param> public override void ReadMessage(MessageReader reader) { Message = reader.ReadString(); Name = reader.ReadString(); Level = reader.ReadInt32(); League = reader.ReadInt32(); UserID = reader.ReadInt64(); CurrentUserID = reader.ReadInt64(); if (reader.ReadBoolean()) { Clan.ID = reader.ReadInt64(); Clan.Name = reader.ReadString(); Clan.Badge = reader.ReadInt32(); } }
public static void HandleSyncTimeRequest(ClientObject client, byte[] messageData) { ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.SYNC_TIME_REPLY; using (MessageWriter mw = new MessageWriter()) { using (MessageReader mr = new MessageReader(messageData)) { //Client send time mw.Write<long>(mr.Read<long>()); //Server receive time mw.Write<long>(DateTime.UtcNow.Ticks); newMessage.data = mw.GetMessageBytes(); } } ClientHandler.SendToClient(client, newMessage, true); }
public static MessageReader GetReader(DirectoryInfo folder, string stream) { var streamDir = Path.Combine(folder.FullName, stream); var di = new DirectoryInfo(streamDir); if (!di.Exists) { di.Create(); } var pagesFile = new FileInfo(Path.Combine(di.FullName, Constants.StreamFileName)); var checkpointFile = new FileInfo(Path.Combine(di.FullName, Constants.PositionFileName)); var pages = new FilePageReader(pagesFile); var checkpoint = new FileCheckpointReader(checkpointFile); var reader = new MessageReader(checkpoint, pages); return reader; }
public override Data Read(MessageReader reader) { return(new Data(reader.ReadString())); }
public static void Postfix(byte ACCJCEHMKLN, MessageReader HFPCBBHJIPJ) { switch (ACCJCEHMKLN) { case (byte)RPC.SetInfected: { HFPCBBHJIPJ.Position = 2; Metamorphosis.Logger.LogMessage(String.Format("HandleRpc SetInfected")); Metamorphosis.Logger.LogMessage(String.Format($"HandleRpc SetInfected MessageReader Length: {HFPCBBHJIPJ.Length}")); Metamorphosis.Logger.LogMessage(String.Format($"HandleRpc SetInfected MessageReader BytesRemaining: {HFPCBBHJIPJ.BytesRemaining}")); byte[] infections = HFPCBBHJIPJ.ReadBytesAndSize(); Metamorphosis.Logger.LogMessage(String.Format($"HandleRpc SetInfected Length: {infections.Length}")); InitMetamorphs(); foreach (byte infectedId in infections) { PlayerControl infectedControl = GetPlayerControlById(infectedId); if (infectedControl != null) { Metamorphosis.Logger.LogMessage(String.Format($"HandleRpc SetInfected Add Metamorph: {infectedId}")); Metamorphs.Add(new Metamorph(infectedControl)); } if (infectedControl.PlayerId == PlayerControl.LocalPlayer.PlayerId) { Metamorphosis.Logger.LogMessage(String.Format($"HandleRpc SetInfected MorphButton StartCooldown: {infectedControl.PlayerId}")); if (HudManagerPatch.MorphButton != null) { HudManagerPatch.MorphButton.StartCooldown(HudManagerPatch.MorphButton.CooldownDuration + 9.0f); } } } Metamorphosis.Logger.LogMessage(String.Format("HandleRpc SetInfected metamorphs created")); //HFPCBBHJIPJ.Position = 0; break; } case (byte)CustomRPC.SyncCustomSettings: { break; } case (byte)RPC.SetName: { Metamorphosis.Logger.LogMessage(String.Format("HandleRpc SetName")); if (Metamorphs != null) { if (IsMetamorph(PlayerControl.LocalPlayer)) { foreach (Metamorph metamorph in Metamorphs) { metamorph.SetOriginalName(); } } } break; } case (byte)RPC.SetColor: { Metamorphosis.Logger.LogMessage("HandleRpc SetColor"); break; } case (byte)RPC.SetSkin: { Metamorphosis.Logger.LogMessage("HandleRpc SetSkin"); break; } case (byte)RPC.SetHat: { Metamorphosis.Logger.LogMessage("HandleRpc SetHat"); break; } case (byte)RPC.SetPet: { Metamorphosis.Logger.LogMessage("HandleRpc SetPet"); break; } case (byte)RPC.StartMeeting: { Metamorphosis.Logger.LogMessage("HandleRpc StartMeeting"); if (PlayerControlPatch.Metamorphs != null) { foreach (Metamorph metamorph in PlayerControlPatch.Metamorphs) { metamorph.MorphBack(); } } break; } } }
private void HandleSignal(Message msg) { switch (msg.Header.Interface) { case "org.freedesktop.DBus": switch (msg.Header.Member) { case "NameAcquired": case "NameLost": { MessageReader reader = new MessageReader(msg, null); var name = reader.ReadString(); bool aquiredNotLost = msg.Header.Member == "NameAcquired"; OnNameAcquiredOrLost(name, aquiredNotLost); return; } case "NameOwnerChanged": { MessageReader reader = new MessageReader(msg, null); var serviceName = reader.ReadString(); if (serviceName[0] == ':') { return; } var oldOwner = reader.ReadString(); oldOwner = string.IsNullOrEmpty(oldOwner) ? null : oldOwner; var newOwner = reader.ReadString(); newOwner = string.IsNullOrEmpty(newOwner) ? null : newOwner; Action <ServiceOwnerChangedEventArgs, Exception> watchers = null; var splitName = serviceName.Split(s_dot); var keys = new string[splitName.Length + 2]; keys[0] = ".*"; var sb = new StringBuilder(); for (int i = 0; i < splitName.Length; i++) { sb.Append(splitName[i]); sb.Append(".*"); keys[i + 1] = sb.ToString(); sb.Remove(sb.Length - 1, 1); } keys[keys.Length - 1] = serviceName; lock (_gate) { foreach (var key in keys) { Action <ServiceOwnerChangedEventArgs, Exception> keyWatchers = null; if (_nameOwnerWatchers?.TryGetValue(key, out keyWatchers) == true) { watchers += keyWatchers; } } } watchers?.Invoke(new ServiceOwnerChangedEventArgs(serviceName, oldOwner, newOwner), null); return; } default: break; } break; default: break; } SignalMatchRule rule = new SignalMatchRule() { Interface = msg.Header.Interface, Member = msg.Header.Member, Path = msg.Header.Path.Value }; SignalHandler signalHandler = null; lock (_gate) { if (_signalHandlers?.TryGetValue(rule, out signalHandler) == true) { try { signalHandler(msg, null); } catch (Exception e) { throw new InvalidOperationException("Signal handler for " + msg.Header.Interface + "." + msg.Header.Member + " threw an exception", e); } } } }
/// <summary> /// Handles incoming messages. /// </summary> /// <param name="sender">The <see cref="IMessageConnection"/> instance from which the message originated.</param> /// <param name="message">The message.</param> public async void HandleMessageRead(object sender, byte[] message) { var code = new MessageReader <MessageCode.Server>(message).ReadCode(); if (code != MessageCode.Server.SearchRequest) { Diagnostic.Debug($"Server message received: {code}"); } try { switch (code) { case MessageCode.Server.ParentMinSpeed: case MessageCode.Server.ParentSpeedRatio: case MessageCode.Server.WishlistInterval: case MessageCode.Server.CheckPrivileges: SoulseekClient.Waiter.Complete(new WaitKey(code), IntegerResponse.FromByteArray <MessageCode.Server>(message)); break; case MessageCode.Server.NewPassword: var confirmedPassword = NewPassword.FromByteArray(message).Password; SoulseekClient.Waiter.Complete(new WaitKey(code), confirmedPassword); break; case MessageCode.Server.GlobalAdminMessage: var msg = GlobalMessageNotification.FromByteArray(message); GlobalMessageReceived?.Invoke(this, new GlobalMessageReceivedEventArgs(msg)); break; case MessageCode.Server.Ping: SoulseekClient.Waiter.Complete(new WaitKey(code)); break; case MessageCode.Server.Login: SoulseekClient.Waiter.Complete(new WaitKey(code), LoginResponse.FromByteArray(message)); break; case MessageCode.Server.RoomList: var roomList = RoomListResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code), roomList); RoomListReceived?.Invoke(this, new RoomListReceivedEventArgs(roomList)); break; case MessageCode.Server.PrivilegedUsers: var privilegedUserList = PrivilegedUserListNotification.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code), privilegedUserList); PrivilegedUserListReceived?.Invoke(this, new PrivilegedUserListReceivedEventArgs(privilegedUserList)); break; case MessageCode.Server.AddPrivilegedUser: PrivilegeNotificationReceived?.Invoke(this, new PrivilegeNotificationReceivedEventArgs(PrivilegedUserNotification.FromByteArray(message))); break; case MessageCode.Server.NotifyPrivileges: var pn = PrivilegeNotification.FromByteArray(message); PrivilegeNotificationReceived?.Invoke(this, new PrivilegeNotificationReceivedEventArgs(pn.Username, pn.Id)); if (SoulseekClient.Options.AutoAcknowledgePrivilegeNotifications) { await SoulseekClient.AcknowledgePrivilegeNotificationAsync(pn.Id, CancellationToken.None).ConfigureAwait(false); } break; case MessageCode.Server.UserPrivileges: var privilegeResponse = UserPrivilegeResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, privilegeResponse.Username), privilegeResponse.IsPrivileged); break; case MessageCode.Server.NetInfo: var netInfo = NetInfoNotification.FromByteArray(message); try { var parents = netInfo.Parents.Select(parent => (parent.Username, new IPEndPoint(parent.IPAddress, parent.Port))); await SoulseekClient.DistributedConnectionManager.AddParentConnectionAsync(parents).ConfigureAwait(false); } catch (Exception ex) { Diagnostic.Debug($"Error handling NetInfo message: {ex.Message}"); } break; case MessageCode.Server.ConnectToPeer: ConnectToPeerResponse connectToPeerResponse = default; try { connectToPeerResponse = ConnectToPeerResponse.FromByteArray(message); if (connectToPeerResponse.Type == Constants.ConnectionType.Transfer) { Diagnostic.Debug($"Received transfer ConnectToPeer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPEndPoint}) for remote token {connectToPeerResponse.Token}"); // ensure that we are expecting at least one file from this user before we connect. the response // doesn't contain any other identifying information about the file. if (!SoulseekClient.Downloads.IsEmpty && SoulseekClient.Downloads.Values.Any(d => d.Username == connectToPeerResponse.Username)) { var(connection, remoteToken) = await SoulseekClient.PeerConnectionManager.GetTransferConnectionAsync(connectToPeerResponse).ConfigureAwait(false); var download = SoulseekClient.Downloads.Values.FirstOrDefault(v => v.RemoteToken == remoteToken && v.Username == connectToPeerResponse.Username); if (download != default(TransferInternal)) { Diagnostic.Debug($"Solicited inbound transfer connection to {download.Username} ({connection.IPEndPoint}) for token {download.Token} (remote: {download.RemoteToken}) established. (id: {connection.Id})"); SoulseekClient.Waiter.Complete(new WaitKey(Constants.WaitKey.IndirectTransfer, download.Username, download.Filename, download.RemoteToken), connection); } else { Diagnostic.Debug($"Transfer ConnectToPeer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPEndPoint}) for remote token {connectToPeerResponse.Token} does not match any waiting downloads, discarding."); connection.Disconnect($"Unknown transfer"); } } else { throw new SoulseekClientException($"Unexpected transfer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPEndPoint}); Ignored"); } } else if (connectToPeerResponse.Type == Constants.ConnectionType.Peer) { Diagnostic.Debug($"Received message ConnectToPeer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPEndPoint})"); await SoulseekClient.PeerConnectionManager.GetOrAddMessageConnectionAsync(connectToPeerResponse).ConfigureAwait(false); } else if (connectToPeerResponse.Type == Constants.ConnectionType.Distributed) { Diagnostic.Debug($"Received distributed ConnectToPeer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPEndPoint})"); await SoulseekClient.DistributedConnectionManager.AddChildConnectionAsync(connectToPeerResponse).ConfigureAwait(false); } else { throw new MessageException($"Unknown Connect To Peer connection type '{connectToPeerResponse.Type}'"); } } catch (Exception ex) { Diagnostic.Debug($"Error handling ConnectToPeer response from {connectToPeerResponse?.Username} ({connectToPeerResponse?.IPEndPoint}): {ex.Message}"); } break; case MessageCode.Server.AddUser: var addUserResponse = AddUserResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, addUserResponse.Username), addUserResponse); break; case MessageCode.Server.GetStatus: var statsResponse = UserStatusResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, statsResponse.Username), statsResponse); UserStatusChanged?.Invoke(this, new UserStatusChangedEventArgs(statsResponse)); break; case MessageCode.Server.PrivateMessage: var pm = PrivateMessageNotification.FromByteArray(message); PrivateMessageReceived?.Invoke(this, new PrivateMessageReceivedEventArgs(pm)); if (SoulseekClient.Options.AutoAcknowledgePrivateMessages) { await SoulseekClient.AcknowledgePrivateMessageAsync(pm.Id, CancellationToken.None).ConfigureAwait(false); } break; case MessageCode.Server.GetPeerAddress: var peerAddressResponse = UserAddressResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, peerAddressResponse.Username), peerAddressResponse); break; case MessageCode.Server.JoinRoom: var roomData = RoomJoinResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, roomData.Name), roomData); break; case MessageCode.Server.LeaveRoom: var leaveRoomResponse = RoomLeaveResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, leaveRoomResponse.RoomName)); break; case MessageCode.Server.SayInChatRoom: var roomMessage = RoomMessageNotification.FromByteArray(message); RoomMessageReceived?.Invoke(this, new RoomMessageReceivedEventArgs(roomMessage)); break; case MessageCode.Server.UserJoinedRoom: var joinNotification = RoomJoinedNotification.FromByteArray(message); RoomJoined?.Invoke(this, new RoomJoinedEventArgs(joinNotification)); break; case MessageCode.Server.UserLeftRoom: var leftNotification = RoomLeftNotification.FromByteArray(message); RoomLeft?.Invoke(this, new RoomLeftEventArgs(leftNotification)); break; case MessageCode.Server.KickedFromServer: KickedFromServer?.Invoke(this, EventArgs.Empty); break; case MessageCode.Server.FileSearch: var searchRequest = ServerSearchRequest.FromByteArray(message); // sometimes (most of the time?) a room search will result in a request to ourselves (assuming we are // joined to it) if (searchRequest.Username == SoulseekClient.Username) { break; } SearchResponse searchResponse; if (SoulseekClient.Options.SearchResponseResolver == default) { break; } try { searchResponse = await SoulseekClient.Options.SearchResponseResolver(searchRequest.Username, searchRequest.Token, SearchQuery.FromText(searchRequest.Query)).ConfigureAwait(false); if (searchResponse != null && searchResponse.FileCount > 0) { var endpoint = await SoulseekClient.GetUserEndPointAsync(searchRequest.Username).ConfigureAwait(false); var peerConnection = await SoulseekClient.PeerConnectionManager.GetOrAddMessageConnectionAsync(searchRequest.Username, endpoint, CancellationToken.None).ConfigureAwait(false); await peerConnection.WriteAsync(searchResponse.ToByteArray()).ConfigureAwait(false); } } catch (Exception ex) { Diagnostic.Warning($"Error resolving search response for query '{searchRequest.Query}' requested by {searchRequest.Username} with token {searchRequest.Token}: {ex.Message}", ex); } break; // if we fail to connect to a distributed parent in a timely manner, the server will begin to send us distributed search requests directly. // forward these to the distributed message handler. case MessageCode.Server.SearchRequest: SoulseekClient.DistributedMessageHandler.HandleMessageRead(SoulseekClient.ServerConnection, message); break; default: Diagnostic.Debug($"Unhandled server message: {code}; {message.Length} bytes"); break; } } catch (Exception ex) { Diagnostic.Warning($"Error handling server message: {code}; {ex.Message}", ex); } }