private void OnHousingWardInfo(IntPtr dataPtr) { HousingWardInfo wardInfo = HousingWardInfo.Read(dataPtr); PluginLog.LogDebug($"Got HousingWardInfo for ward: {wardInfo.LandIdent.WardNumber} territory: {wardInfo.LandIdent.TerritoryTypeId}"); // if the current wardinfo is for a different district than the last swept one, print the header\ // or if the last sweep was > 10m ago if (wardInfo.LandIdent.WorldId != lastSweptDistrictWorldId || wardInfo.LandIdent.TerritoryTypeId != lastSweptDistrictTerritoryTypeId || lastSweepTime < (DateTime.Now - TimeSpan.FromMinutes(10))) { // reset last sweep info to the current sweep lastSweptDistrictWorldId = wardInfo.LandIdent.WorldId; lastSweptDistrictTerritoryTypeId = wardInfo.LandIdent.TerritoryTypeId; lastSweptDistrictSeenWardNumbers.Clear(); lastSweepTime = DateTime.Now; var districtName = this.territories.GetRow((uint)wardInfo.LandIdent.TerritoryTypeId).PlaceName.Value.Name; var worldName = this.worlds.GetRow((uint)wardInfo.LandIdent.WorldId).Name; this.pi.Framework.Gui.Chat.Print($"Began sweep for {districtName} ({worldName})"); } // if we've seen this ward already, ignore it if (lastSweptDistrictSeenWardNumbers.Contains(wardInfo.LandIdent.WardNumber)) { PluginLog.LogDebug($"Skipped processing HousingWardInfo for ward: {wardInfo.LandIdent.WardNumber} because we have seen it already"); return; } // add the ward number to this sweep's seen numbers lastSweptDistrictSeenWardNumbers.Add(wardInfo.LandIdent.WardNumber); // if that's all the wards, give the user a cookie if (lastSweptDistrictSeenWardNumbers.Count == numWardsPerDistrict) { this.pi.Framework.Gui.Chat.Print($"Swept all {numWardsPerDistrict} wards. Thank you!"); } // iterate over houses to find open houses for (int i = 0; i < wardInfo.HouseInfoEntries.Length; i++) { HouseInfoEntry houseInfoEntry = wardInfo.HouseInfoEntries[i]; PluginLog.LogVerbose( $"Got {wardInfo.LandIdent.WardNumber + 1}-{i + 1}: owned by {houseInfoEntry.EstateOwnerName}, flags {houseInfoEntry.InfoFlags}, price {houseInfoEntry.HousePrice}"); if ((houseInfoEntry.InfoFlags & HousingFlags.PlotOwned) == 0) { this.OnFoundOpenHouse(wardInfo, houseInfoEntry, i); } } PluginLog.LogDebug($"Done processing HousingWardInfo for ward: {wardInfo.LandIdent.WardNumber}"); }
private void OnFoundOpenHouse(HousingWardInfo wardInfo, HouseInfoEntry houseInfoEntry, int plotNumber) { var place = this.territories.GetRow((uint)wardInfo.LandIdent.TerritoryTypeId).PlaceName.Value; var districtName = place.NameNoArticle.RawString.Length > 0 ? place.NameNoArticle : place.Name; // languages like German do not use NameNoArticle (#2) var worldName = this.worlds.GetRow((uint)wardInfo.LandIdent.WorldId).Name; // gross way of getting the landset from the territorytype but the game does not send the correct landsetid uint landSetIndex = (uint)wardInfo.LandIdent.TerritoryTypeId - 339; landSetIndex = landSetIndex > 3 ? 3 : landSetIndex; var houseSize = this.housingLandSets.GetRow(landSetIndex).PlotSize[plotNumber]; var districtNameNoSpaces = districtName.ToString().Replace(" ", ""); int wardNum = wardInfo.LandIdent.WardNumber + 1; int plotNum = plotNumber + 1; float housePriceMillions = houseInfoEntry.HousePrice / 1000000f; string houseSizeName = houseSize == 0 ? "Small" : houseSize == 1 ? "Medium" : "Large"; pi.CommandManager.ProcessCommand("/hsplotnotify " + wardNum.ToString()); string output; switch (configuration.OutputFormat) { case OutputFormat.Pings: output = $"@{houseSizeName}{districtNameNoSpaces} {wardNum}-{plotNum} ({housePriceMillions:F3}m)"; break; case OutputFormat.EnoBot: output = $"##forsale {districtNameNoSpaces} w{wardNum} p{plotNum}"; break; case OutputFormat.Custom: output = FormatCustomOutputString(this.configuration.OutputFormatString, districtName.ToString(), districtNameNoSpaces, worldName, wardNum.ToString(), plotNum.ToString(), houseInfoEntry.HousePrice.ToString(), housePriceMillions.ToString("F3"), houseSizeName); break; default: output = $"{districtName} {wardNum}-{plotNum} ({housePriceMillions:F3}m)"; break; } this.pi.Framework.Gui.Chat.Print(output); }
private void DataSubscriptionOnNetworkReceived(string connection, long epoch, byte[] message) { //Log($"{connection}: {epoch.ToString("X")}"); var opCode = BitConverter.ToInt16(message, 0x12); if (checkbox_sendraw.Checked) { if (current_player != FfxivPlugin.DataRepository.GetCurrentPlayerID() || last_update_time < DateTimeOffset.Now.ToUnixTimeSeconds() - 10) { current_player = FfxivPlugin.DataRepository.GetCurrentPlayerID(); last_update_time = DateTimeOffset.Now.ToUnixTimeSeconds(); this.SendText(new JavaScriptSerializer().Serialize(new { playerID = current_player, worldID = CurrentWorldId }), "metadata"); } this.SendRaw(message, "raw", epoch); } if (opCode == 350) { var listing = HousingWardInfo.Read(message.Skip(0x20).ToArray(), this); return; } }