/// <summary> /// Handles EnsembleStart /// </summary> /// <param name="timeStamp"></param> /// <param name="otherActorId"></param> /// <param name="myActorId"></param> /// <param name="message"></param> internal void Size88(long timeStamp, uint otherActorId, uint myActorId, byte[] message) { try { if (otherActorId != myActorId) { return; } var partyLeader = BitConverter.ToUInt32(message, 40); if ( !ActorIdTools.RangeOkay(partyLeader) || !(BitConverter.ToUInt16(message, 48) == 0 && ValidTempo(message[50]) && ValidTimeSig(message[51])) || // 00 00 [tempo] [timesig] BitConverter.ToUInt32(message, 44) > 0 || // These should all be zero in an ensemble start packet. BitConverter.ToUInt32(message, 52) > 0 || BitConverter.ToUInt32(message, 56) > 0 || BitConverter.ToUInt32(message, 60) > 0 || BitConverter.ToUInt32(message, 64) > 0 || BitConverter.ToUInt32(message, 68) > 0 || BitConverter.ToUInt32(message, 72) > 0 || BitConverter.ToUInt32(message, 76) > 0 ) { return; } _machinaReader.ReaderHandler.Game.PublishEvent(new EnsembleStarted(EventSource.Machina)); } catch (Exception ex) { _machinaReader.ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, new BmpSeerMachinaException("Exception in Packet.Size88 (ensemble action): " + ex.Message))); } }
public KeyValuePair <uint, (string, bool)> GetCurrentPlayer() { var result = new KeyValuePair <uint, (string, bool)>(); if (!CanGetPlayerInfo() || !MemoryHandler.IsAttached) { return(result); } var playerInfoMap = (IntPtr)Scanner.Locations[Signatures.PlayerInformationKey]; if (playerInfoMap.ToInt64() <= 6496) { return(result); } try { var source = MemoryHandler.GetByteArray(playerInfoMap, MemoryHandler.Structures.CurrentPlayer.SourceSize); var actorId = SBitConverter.TryToUInt32(source, MemoryHandler.Structures.CurrentPlayer.ID); var playerName = MemoryHandler.GetStringFromBytes(source, MemoryHandler.Structures.CurrentPlayer.Name); var isCurrentlyBard = source[MemoryHandler.Structures.CurrentPlayer.JobID] == 0x17; if (ActorIdTools.RangeOkay(actorId) && !string.IsNullOrEmpty(playerName)) { result = new KeyValuePair <uint, (string, bool)>(actorId, (playerName, isCurrentlyBard)); } } catch (Exception ex) { MemoryHandler?.RaiseException(ex); } return(result); }
public SortedDictionary <uint, string> GetPartyMembers() { var result = new SortedDictionary <uint, string>(); if (!CanGetPartyMembers() || !MemoryHandler.IsAttached) { return(result); } var partyInfoMap = (IntPtr)Scanner.Locations[Signatures.PartyMapKey]; var partyCountMap = Scanner.Locations[Signatures.PartyCountKey]; try { var partyCount = MemoryHandler.GetByte(partyCountMap); var sourceSize = MemoryHandler.Structures.PartyMember.SourceSize; if (partyCount > 1 && partyCount < 9) { for (uint i = 0; i < partyCount; i++) { var address = partyInfoMap.ToInt64() + i * (uint)sourceSize; var source = MemoryHandler.GetByteArray(new IntPtr(address), sourceSize); var actorId = SBitConverter.TryToUInt32(source, MemoryHandler.Structures.PartyMember.ID); var playerName = MemoryHandler.GetStringFromBytes(source, MemoryHandler.Structures.PartyMember.Name); if (ActorIdTools.RangeOkay(actorId) && !string.IsNullOrEmpty(playerName)) { result[actorId] = playerName; } } } if (result.Count == 1) { result.Clear(); } } catch (Exception ex) { MemoryHandler?.RaiseException(ex); } return(result); }
/// <summary> /// Contains party information like hp. Does not contain PlayerName. A reference Id is cached for PlayerName lookup in Size928 that comes next. /// </summary> /// <param name="timeStamp"></param> /// <param name="otherActorId"></param> /// <param name="myActorId"></param> /// <param name="message"></param> internal void Size3576(long timeStamp, uint otherActorId, uint myActorId, byte[] message) { try { if (otherActorId != myActorId) { return; } for (var i = 0; i <= 3080; i += 440) // 8 iterations. cache contentId -> actorId. Size928 is fired next which only references the contentId { var actorId = BitConverter.ToUInt32(message, 72 + i); if (ActorIdTools.RangeOkay(actorId)) { _contentId2ActorId[BitConverter.ToUInt64(message, 64 + i)] = actorId; } } } catch (Exception ex) { _machinaReader.ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, new BmpSeerMachinaException("Exception in Packet.Size3576 (party): " + ex.Message))); } }
public override bool IsValid() => ActorIdTools.RangeOkay(ActorId);
/// <summary> /// Handles Ensemble Request, Ensemble Reject, and Instrument Equip/De-Equip. /// </summary> /// <param name="timeStamp"></param> /// <param name="otherActorId"></param> /// <param name="myActorId"></param> /// <param name="message"></param> internal void Size56(long timeStamp, uint otherActorId, uint myActorId, byte[] message) { try { if (otherActorId != myActorId || BitConverter.ToUInt32(message, 44) != 0) { return; } if (BitConverter.ToUInt16(message, 32) != 2 && !( BitConverter.ToUInt32(message, 36) == 16 && BitConverter.ToUInt32(message, 40) > 0 && BitConverter.ToUInt32(message, 40) < 64 && BitConverter.ToUInt32(message, 44) == 0 && BitConverter.ToUInt32(message, 48) == 0 || BitConverter.ToUInt32(message, 36) == 1 && BitConverter.ToUInt32(message, 40) == 0 && BitConverter.ToUInt32(message, 44) == 0 && BitConverter.ToUInt32(message, 48) == 0 )) { try { if (BitConverter.ToUInt16(message, 48) == 0 && ValidTempo(message[50]) && ValidTimeSig(message[51]) ) // 00 00 [tempo] [timesig] { var partyLeader = BitConverter.ToUInt32(message, 40); if (!ActorIdTools.RangeOkay(partyLeader)) { return; } _machinaReader.ReaderHandler.Game.PublishEvent(new EnsembleRequested(EventSource.Machina)); } else { var partyMember = BitConverter.ToUInt32(message, 40); if (!ActorIdTools.RangeOkay(partyMember)) { return; } uint reply = message[48]; if (reply > 2) { return; } switch (reply) { case 0: // no instrument equipped reply. break; case 1: // "ready" reply. break; case 2: // rejected or timed out replying _machinaReader.ReaderHandler.Game.PublishEvent(new EnsembleRejected(EventSource.Machina)); break; default: return; } } } catch (Exception ex) { _machinaReader.ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, new BmpSeerMachinaException("Exception in Packet.Size56 (ensemble action): " + ex.Message))); } } else { try { var category = BitConverter.ToUInt16(message, 32); // category switch (category) { case 2: // instrument equip/dequip is in this category var param1 = BitConverter.ToUInt32(message, 36); // action. var param2 = BitConverter.ToUInt32(message, 40); var param3 = BitConverter.ToUInt32(message, 44); var param4 = BitConverter.ToUInt32(message, 48); if (param3 == 0 && param4 == 0) { switch (param1) { case 16: // equip instrument _machinaReader.ReaderHandler.Game.PublishEvent(new InstrumentHeldChanged(EventSource.Machina, Instrument.Parse((int)param2))); break; case 1: // de-equip instrument if (param2 == 0) { _machinaReader.ReaderHandler.Game.PublishEvent(new InstrumentHeldChanged(EventSource.Machina, Instrument.Parse((int)param2))); } break; } } break; } } catch (Exception ex) { _machinaReader.ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, new BmpSeerMachinaException("Exception in Packet.Size56 (equip action): " + ex.Message))); } } } catch (Exception ex) { _machinaReader.ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, new BmpSeerMachinaException("Exception in Packet.Size56: " + ex.Message))); } }
public async Task Loop(CancellationToken token) { _messageQueue = new ConcurrentQueue <byte[]>(); _messageQueueOpen = true; _packet = new Packet(this); MachinaManager.Instance.MessageReceived += OnMessageReceived; MachinaManager.Instance.AddGame(ReaderHandler.Game.Pid); while (!token.IsCancellationRequested) { while (_messageQueue.TryDequeue(out var message)) { try { var otherActorId = BitConverter.ToUInt32(message, 4); var myActorId = BitConverter.ToUInt32(message, 8); long timeStamp = BitConverter.ToUInt32(message, 24); timeStamp *= 1000; if (!(ActorIdTools.RangeOkay(myActorId) && ActorIdTools.RangeOkay(otherActorId))) { continue; } if (myActorId == otherActorId) { ReaderHandler.Game.PublishEvent(new ActorIdChanged(EventSource.Machina, myActorId)); } switch (message.Length) { case 56: _packet.Size56(timeStamp, otherActorId, myActorId, message); break; case 88: _packet.Size88(timeStamp, otherActorId, myActorId, message); break; case 656: _packet.Size656(timeStamp, otherActorId, myActorId, message); break; case 664: _packet.Size664(timeStamp, otherActorId, myActorId, message); break; case 928: _packet.Size928(timeStamp, otherActorId, myActorId, message); break; case 3576: _packet.Size3576(timeStamp, otherActorId, myActorId, message); break; default: ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, new BmpSeerMachinaException("Unknown packet size: " + message.Length))); break; } } catch (Exception ex) { ReaderHandler.Game.PublishEvent(new BackendExceptionEvent(EventSource.Machina, ex)); } } await Task.Delay(SleepTimeInMs, token); } }