refactor: move to net5

This commit is contained in:
Anna 2021-08-24 14:00:42 -04:00
parent 26c9b878f3
commit 6113c04093
Signed by: anna
GPG Key ID: 0B391D8F06FCD9E0
12 changed files with 230 additions and 107 deletions

View File

@ -1,10 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<TargetFramework>net5-windows</TargetFramework>
<Version>1.2.0</Version>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
@ -12,6 +15,10 @@
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="FFXIVClientStructs">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\FFXIVClientStructs.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ImGui.NET">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGui.NET.dll</HintPath>
<Private>False</Private>
@ -28,17 +35,15 @@
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Memory">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\System.Memory.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="1.2.1"/>
<PackageReference Include="Fody" Version="6.5.1" PrivateAssets="all"/>
<PackageReference Include="ILMerge.Fody" Version="1.16.0" PrivateAssets="all"/>
<PackageReference Include="XivCommon" Version="1.5.0"/>
<PackageReference Include="DalamudPackager" Version="2.1.2"/>
<PackageReference Include="XivCommon" Version="3.0.1"/>
</ItemGroup>
<ItemGroup>
<Content Include="..\icon.png" Link="images/icon.png" CopyToOutputDirectory="PreserveNewest" Visible="false"/>
</ItemGroup>
</Project>

View File

@ -1,5 +1,6 @@
author: ascclemens
name: Better Party Finder
punchline: Use advanced Party Finder filter presets.
description: |-
Filter the party finder better.

View File

@ -14,16 +14,16 @@ namespace BetterPartyFinder {
internal Commands(Plugin plugin) {
this.Plugin = plugin;
foreach (var name in CommandNames) {
this.Plugin.Interface.CommandManager.AddHandler(name.Key, new CommandInfo(this.OnCommand) {
HelpMessage = name.Value,
foreach (var (name, help) in CommandNames) {
this.Plugin.CommandManager.AddHandler(name, new CommandInfo(this.OnCommand) {
HelpMessage = help,
});
}
}
public void Dispose() {
foreach (var name in CommandNames.Keys) {
this.Plugin.Interface.CommandManager.RemoveHandler(name);
this.Plugin.CommandManager.RemoveHandler(name);
}
}

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Dalamud.Configuration;
using Dalamud.Game.Internal.Gui.Structs;
using Dalamud.Game.Gui.PartyFinder.Types;
namespace BetterPartyFinder {
public class Configuration : IPluginConfiguration {
@ -120,7 +120,7 @@ namespace BetterPartyFinder {
Conditions = this.Conditions,
Duties = duties,
Jobs = jobs,
Name = string.Copy(this.Name),
Name = new string(this.Name),
Objectives = this.Objectives,
DutiesMode = this.DutiesMode,
LootRule = this.LootRule,

View File

@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dalamud.Game.Internal.Gui;
using Dalamud.Game.Internal.Gui.Structs;
using Dalamud.Game.Gui.PartyFinder.Types;
namespace BetterPartyFinder {
public class Filter : IDisposable {
@ -11,11 +10,11 @@ namespace BetterPartyFinder {
internal Filter(Plugin plugin) {
this.Plugin = plugin;
this.Plugin.Interface.Framework.Gui.PartyFinder.ReceiveListing += this.ReceiveListing;
this.Plugin.PartyFinderGui.ReceiveListing += this.ReceiveListing;
}
public void Dispose() {
this.Plugin.Interface.Framework.Gui.PartyFinder.ReceiveListing -= this.ReceiveListing;
this.Plugin.PartyFinderGui.ReceiveListing -= this.ReceiveListing;
}
private void ReceiveListing(PartyFinderListing listing, PartyFinderListingEventArgs args) {
@ -77,7 +76,7 @@ namespace BetterPartyFinder {
}
// filter based on category (slow)
if (!filter.Categories.Any(category => category.ListingMatches(this.Plugin.Interface.Data, listing))) {
if (!filter.Categories.Any(category => category.ListingMatches(this.Plugin.DataManager, listing))) {
return false;
}
@ -109,7 +108,7 @@ namespace BetterPartyFinder {
continue;
}
var job = possibleJob.ClassJob(this.Plugin.Interface.Data);
var job = possibleJob.ClassJob(this.Plugin.DataManager);
if (present.Contains((byte) job.RowId)) {
continue;
}

View File

@ -1,3 +0,0 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ILMerge/>
</Weavers>

View File

@ -1,5 +1,5 @@
using System;
using Dalamud.Game.Internal.Gui.Structs;
using Dalamud.Game.Gui.PartyFinder.Types;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
@ -25,10 +25,10 @@ namespace BetterPartyFinder {
SeString msg = "Party description: ";
msg.Payloads.AddRange(listing.Description.Payloads);
this.Plugin.Interface.Framework.Gui.Chat.PrintChat(new XivChatEntry {
this.Plugin.ChatGui.PrintChat(new XivChatEntry {
Name = "Better Party Finder",
Type = XivChatType.SystemMessage,
MessageBytes = msg.Encode(),
Message = msg,
});
}
}

View File

@ -1,4 +1,11 @@
using Dalamud.Plugin;
using Dalamud.Data;
using Dalamud.Game.ClientState;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.Game.Gui.PartyFinder;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.IoC;
using Dalamud.Plugin;
using XivCommon;
namespace BetterPartyFinder {
@ -6,28 +13,49 @@ namespace BetterPartyFinder {
public class Plugin : IDalamudPlugin {
public string Name => "Better Party Finder";
internal DalamudPluginInterface Interface { get; private set; } = null!;
internal Configuration Config { get; private set; } = null!;
private Filter Filter { get; set; } = null!;
internal PluginUi Ui { get; private set; } = null!;
private Commands Commands { get; set; } = null!;
internal XivCommonBase Common { get; private set; } = null!;
private JoinHandler JoinHandler { get; set; } = null!;
[PluginService]
internal DalamudPluginInterface Interface { get; init; } = null!;
public void Initialize(DalamudPluginInterface pluginInterface) {
this.Interface = pluginInterface;
[PluginService]
internal ChatGui ChatGui { get; init; } = null!;
[PluginService]
internal ClientState ClientState { get; init; } = null!;
[PluginService]
internal CommandManager CommandManager { get; init; } = null!;
[PluginService]
internal DataManager DataManager { get; init; } = null!;
[PluginService]
internal GameGui GameGui { get; init; } = null!;
[PluginService]
internal PartyFinderGui PartyFinderGui { get; init; } = null!;
[PluginService]
internal SeStringManager SeStringManager { get; init; } = null!;
internal Configuration Config { get; }
private Filter Filter { get; }
internal PluginUi Ui { get; }
private Commands Commands { get; }
internal XivCommonBase Common { get; }
private JoinHandler JoinHandler { get; }
public Plugin() {
this.Config = Configuration.Load(this) ?? new Configuration();
this.Config.Initialise(this);
this.Common = new XivCommonBase(this.Interface, Hooks.PartyFinder);
this.Common = new XivCommonBase(Hooks.PartyFinder);
this.Filter = new Filter(this);
this.JoinHandler = new JoinHandler(this);
this.Ui = new PluginUi(this);
this.Commands = new Commands(this);
// start task to determine maximum item level (based on max chestpiece)
Util.CalculateMaxItemLevel(this.Interface.Data);
Util.CalculateMaxItemLevel(this.DataManager);
}
public void Dispose() {

View File

@ -3,12 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Data;
using Dalamud.Game.Internal.Gui.Structs;
using Dalamud.Game.Gui.PartyFinder.Types;
using Dalamud.Interface;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Addon = Lumina.Excel.GeneratedSheets.Addon;
using GameAddon = Dalamud.Game.Internal.Gui.Addon.Addon;
namespace BetterPartyFinder {
public class PluginUi : IDisposable {
@ -47,16 +47,16 @@ namespace BetterPartyFinder {
internal PluginUi(Plugin plugin) {
this.Plugin = plugin;
this.Plugin.Interface.UiBuilder.OnBuildUi += this.Draw;
this.Plugin.Interface.UiBuilder.OnOpenConfigUi += this.OnOpenConfig;
this.Plugin.Interface.UiBuilder.Draw += this.Draw;
this.Plugin.Interface.UiBuilder.OpenConfigUi += this.OnOpenConfig;
}
public void Dispose() {
this.Plugin.Interface.UiBuilder.OnBuildUi -= this.Draw;
this.Plugin.Interface.UiBuilder.OnOpenConfigUi -= this.OnOpenConfig;
this.Plugin.Interface.UiBuilder.Draw -= this.Draw;
this.Plugin.Interface.UiBuilder.OpenConfigUi -= this.OnOpenConfig;
}
private void OnOpenConfig(object sender, EventArgs e) {
private void OnOpenConfig() {
this.Visible = !this.Visible;
}
@ -75,8 +75,8 @@ namespace BetterPartyFinder {
return result;
}
private GameAddon? PartyFinderAddon() {
return this.Plugin.Interface.Framework.Gui.GetAddonByName("LookingForGroup", 1);
private IntPtr PartyFinderAddon() {
return this.Plugin.GameGui.GetAddonByName("LookingForGroup", 1);
}
private void Draw() {
@ -125,27 +125,30 @@ namespace BetterPartyFinder {
ImGui.End();
}
private void DrawFiltersWindow() {
private unsafe void DrawFiltersWindow() {
ImGui.SetNextWindowSize(new Vector2(550f, 510f), ImGuiCond.FirstUseEver);
var addon = this.Plugin.Config.ShowWhenPfOpen ? this.PartyFinderAddon() : null;
AtkUnitBase* addon = null;
var addonPtr = this.PartyFinderAddon();
if (this.Plugin.Config.ShowWhenPfOpen && addonPtr != IntPtr.Zero) {
addon = (AtkUnitBase*) addonPtr;
}
var showWindow = this.Visible || addon?.Visible == true;
var showWindow = this.Visible || addon != null && addon->IsVisible;
if (!showWindow) {
return;
}
if (!ImGui.Begin(this.Plugin.Name, ref this._visible, ImGuiWindowFlags.NoDocking)) {
if (ImGui.IsWindowCollapsed() && addon is {Visible: true}) {
if (ImGui.IsWindowCollapsed() && addon != null && addon->IsVisible) {
// wait until addon is initialised to show
try {
_ = addon.Width;
} catch (NullReferenceException) {
var rootNode = addon->RootNode;
if (rootNode == null) {
return;
}
ImGui.SetWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(addon.X, addon.Y - ImGui.GetFrameHeight()));
ImGui.SetWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(addon->X, addon->Y - ImGui.GetFrameHeight()));
}
ImGui.End();
@ -153,10 +156,9 @@ namespace BetterPartyFinder {
}
if (addon != null && this.Plugin.Config.WindowSide == WindowSide.Right) {
try {
ImGui.SetWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(addon.X + addon.Width, addon.Y));
} catch (NullReferenceException) {
// ignore
var rootNode = addon->RootNode;
if (rootNode != null) {
ImGui.SetWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(addon->X + rootNode->Width, addon->Y));
}
}
@ -272,13 +274,10 @@ namespace BetterPartyFinder {
}
if (addon != null && this.Plugin.Config.WindowSide == WindowSide.Left) {
try {
_ = addon.Width;
// only continue if width is set, meaning addon is initialised
var rootNode = addon->RootNode;
if (rootNode != null) {
var currentWidth = ImGui.GetWindowWidth();
ImGui.SetWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(addon.X - currentWidth, addon.Y));
} catch (NullReferenceException) {
// ignore
ImGui.SetWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(addon->X - currentWidth, addon->Y));
}
}
@ -312,7 +311,7 @@ namespace BetterPartyFinder {
foreach (var category in (UiCategory[]) Enum.GetValues(typeof(UiCategory))) {
var selected = filter.Categories.Contains(category);
if (!ImGui.Selectable(category.Name(this.Plugin.Interface.Data), ref selected)) {
if (!ImGui.Selectable(category.Name(this.Plugin.DataManager), ref selected)) {
continue;
}
@ -361,23 +360,23 @@ namespace BetterPartyFinder {
}
if (ImGui.BeginChild("duty-selection", new Vector2(-1f, -1f))) {
var duties = this.Plugin.Interface.Data.GetExcelSheet<ContentFinderCondition>()
var duties = this.Plugin.DataManager.GetExcelSheet<ContentFinderCondition>()!
.Where(cf => cf.Unknown29)
.Where(cf => AllowedContentTypes.Contains(cf.ContentType.Row));
var searchQuery = this.DutySearchQuery.Trim();
if (searchQuery.Trim() != "") {
duties = duties.Where(duty => {
var sestring = this.Plugin.Interface.SeStringManager.Parse(duty.Name.RawData.ToArray());
var sestring = this.Plugin.SeStringManager.Parse(duty.Name.RawData.ToArray());
return sestring.TextValue.ContainsIgnoreCase(searchQuery);
});
}
foreach (var cf in duties) {
var sestring = this.Plugin.Interface.SeStringManager.Parse(cf.Name.RawData.ToArray());
var sestring = this.Plugin.SeStringManager.Parse(cf.Name.RawData.ToArray());
var selected = filter.Duties.Contains(cf.RowId);
var name = sestring.TextValue;
name = char.ToUpperInvariant(name[0]) + name.Substring(1);
name = char.ToUpperInvariant(name[0]) + name[1..];
if (!ImGui.Selectable(name, ref selected)) {
continue;
}
@ -472,7 +471,7 @@ namespace BetterPartyFinder {
foreach (var job in (JobFlags[]) Enum.GetValues(typeof(JobFlags))) {
var selected = (slot & job) > 0;
if (!ImGui.Selectable(job.ClassJob(this.Plugin.Interface.Data)?.Name ?? "???", ref selected)) {
if (!ImGui.Selectable(job.ClassJob(this.Plugin.DataManager)?.Name ?? "???", ref selected)) {
continue;
}
@ -603,7 +602,7 @@ namespace BetterPartyFinder {
private string _playerName = string.Empty;
private void DrawPlayersTab(ConfigurationFilter filter) {
var player = this.Plugin.Interface.ClientState.LocalPlayer;
var player = this.Plugin.ClientState.LocalPlayer;
if (player == null || !ImGui.BeginTabItem("Players")) {
return;
@ -615,7 +614,7 @@ namespace BetterPartyFinder {
ImGui.SameLine();
var worlds = Util.WorldsOnDataCentre(this.Plugin.Interface.Data, player)
var worlds = Util.WorldsOnDataCentre(this.Plugin.DataManager, player)
.OrderBy(world => world.Name.RawString)
.ToList();
@ -642,7 +641,7 @@ namespace BetterPartyFinder {
PlayerInfo? deleting = null;
foreach (var info in filter.Players) {
var world = this.Plugin.Interface.Data.GetExcelSheet<World>().GetRow(info.World);
var world = this.Plugin.DataManager.GetExcelSheet<World>()!.GetRow(info.World);
ImGui.TextUnformatted($"{info.Name}@{world?.Name}");
ImGui.SameLine();
if (IconButton(FontAwesomeIcon.Trash, $"delete-player-{info.GetHashCode()}")) {
@ -679,54 +678,54 @@ namespace BetterPartyFinder {
internal static class UiCategoryExt {
internal static string? Name(this UiCategory category, DataManager data) {
var ct = data.GetExcelSheet<ContentType>();
var addon = data.GetExcelSheet<Addon>();
var ct = data.GetExcelSheet<ContentType>()!;
var addon = data.GetExcelSheet<Addon>()!;
return category switch {
UiCategory.None => addon.GetRow(1_562).Text.ToString(), // best guess
UiCategory.DutyRoulette => ct.GetRow((uint) ContentType2.DutyRoulette).Name.ToString(),
UiCategory.Dungeons => ct.GetRow((uint) ContentType2.Dungeons).Name.ToString(),
UiCategory.Guildhests => ct.GetRow((uint) ContentType2.Guildhests).Name.ToString(),
UiCategory.Trials => ct.GetRow((uint) ContentType2.Trials).Name.ToString(),
UiCategory.Raids => ct.GetRow((uint) ContentType2.Raids).Name.ToString(),
UiCategory.HighEndDuty => addon.GetRow(10_822).Text.ToString(), // best guess
UiCategory.Pvp => ct.GetRow((uint) ContentType2.Pvp).Name.ToString(),
UiCategory.QuestBattles => ct.GetRow((uint) ContentType2.QuestBattles).Name.ToString(),
UiCategory.Fates => ct.GetRow((uint) ContentType2.Fates).Name.ToString(),
UiCategory.TreasureHunt => ct.GetRow((uint) ContentType2.TreasureHunt).Name.ToString(),
UiCategory.TheHunt => addon.GetRow(8_613).Text.ToString(),
UiCategory.GatheringForays => addon.GetRow(2_306).Text.ToString(),
UiCategory.DeepDungeons => ct.GetRow((uint) ContentType2.DeepDungeons).Name.ToString(),
UiCategory.AdventuringForays => addon.GetRow(2_307).Text.ToString(),
UiCategory.None => addon.GetRow(1_562)?.Text.ToString(), // best guess
UiCategory.DutyRoulette => ct.GetRow((uint) ContentType2.DutyRoulette)?.Name.ToString(),
UiCategory.Dungeons => ct.GetRow((uint) ContentType2.Dungeons)?.Name.ToString(),
UiCategory.Guildhests => ct.GetRow((uint) ContentType2.Guildhests)?.Name.ToString(),
UiCategory.Trials => ct.GetRow((uint) ContentType2.Trials)?.Name.ToString(),
UiCategory.Raids => ct.GetRow((uint) ContentType2.Raids)?.Name.ToString(),
UiCategory.HighEndDuty => addon.GetRow(10_822)?.Text.ToString(), // best guess
UiCategory.Pvp => ct.GetRow((uint) ContentType2.Pvp)?.Name.ToString(),
UiCategory.QuestBattles => ct.GetRow((uint) ContentType2.QuestBattles)?.Name.ToString(),
UiCategory.Fates => ct.GetRow((uint) ContentType2.Fates)?.Name.ToString(),
UiCategory.TreasureHunt => ct.GetRow((uint) ContentType2.TreasureHunt)?.Name.ToString(),
UiCategory.TheHunt => addon.GetRow(8_613)?.Text.ToString(),
UiCategory.GatheringForays => addon.GetRow(2_306)?.Text.ToString(),
UiCategory.DeepDungeons => ct.GetRow((uint) ContentType2.DeepDungeons)?.Name.ToString(),
UiCategory.AdventuringForays => addon.GetRow(2_307)?.Text.ToString(),
_ => null,
};
}
internal static bool ListingMatches(this UiCategory category, DataManager data, PartyFinderListing listing) {
var cr = data.GetExcelSheet<ContentRoulette>();
var cr = data.GetExcelSheet<ContentRoulette>()!;
var isDuty = listing.Category == Category.Duty;
var isDuty = listing.Category == DutyCategory.Duty;
var isNormal = listing.DutyType == DutyType.Normal;
var isOther = listing.DutyType == DutyType.Other;
var isNormalDuty = isNormal && isDuty;
return category switch {
UiCategory.None => isOther && isDuty && listing.RawDuty == 0,
UiCategory.DutyRoulette => listing.DutyType == DutyType.Roulette && isDuty && !cr.GetRow(listing.RawDuty).Unknown10,
UiCategory.DutyRoulette => listing.DutyType == DutyType.Roulette && isDuty && (!cr.GetRow(listing.RawDuty)?.Unknown10 ?? false),
UiCategory.Dungeons => isNormalDuty && listing.Duty.Value.ContentType.Row == (uint) ContentType2.Dungeons,
UiCategory.Guildhests => isNormalDuty && listing.Duty.Value.ContentType.Row == (uint) ContentType2.Guildhests,
UiCategory.Trials => isNormalDuty && !listing.Duty.Value.HighEndDuty && listing.Duty.Value.ContentType.Row == (uint) ContentType2.Trials,
UiCategory.Raids => isNormalDuty && !listing.Duty.Value.HighEndDuty && listing.Duty.Value.ContentType.Row == (uint) ContentType2.Raids,
UiCategory.HighEndDuty => isNormalDuty && listing.Duty.Value.HighEndDuty,
UiCategory.Pvp => listing.DutyType == DutyType.Roulette && isDuty && cr.GetRow(listing.RawDuty).Unknown10
UiCategory.Pvp => listing.DutyType == DutyType.Roulette && isDuty && (cr.GetRow(listing.RawDuty)?.Unknown10 ?? false)
|| isNormalDuty && listing.Duty.Value.ContentType.Row == (uint) ContentType2.Pvp,
UiCategory.QuestBattles => isOther && listing.Category == Category.QuestBattles,
UiCategory.Fates => isOther && listing.Category == Category.Fates,
UiCategory.TreasureHunt => isOther && listing.Category == Category.TreasureHunt,
UiCategory.TheHunt => isOther && listing.Category == Category.TheHunt,
UiCategory.GatheringForays => isNormal && listing.Category == Category.GatheringForays,
UiCategory.DeepDungeons => isOther && listing.Category == Category.DeepDungeons,
UiCategory.AdventuringForays => isNormal && listing.Category == Category.AdventuringForays,
UiCategory.QuestBattles => isOther && listing.Category == DutyCategory.QuestBattles,
UiCategory.Fates => isOther && listing.Category == DutyCategory.Fates,
UiCategory.TreasureHunt => isOther && listing.Category == DutyCategory.TreasureHunt,
UiCategory.TheHunt => isOther && listing.Category == DutyCategory.TheHunt,
UiCategory.GatheringForays => isNormal && listing.Category == DutyCategory.GatheringForays,
UiCategory.DeepDungeons => isOther && listing.Category == DutyCategory.DeepDungeons,
UiCategory.AdventuringForays => isNormal && listing.Category == DutyCategory.AdventuringForays,
_ => false,
};
}

View File

@ -2,7 +2,7 @@
using System.Globalization;
using System.Linq;
using Dalamud.Data;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Lumina.Excel.GeneratedSheets;
namespace BetterPartyFinder {
@ -14,8 +14,8 @@ namespace BetterPartyFinder {
return;
}
var max = data.GetExcelSheet<Item>()
.Where(item => item.EquipSlotCategory.Value.Body != 0)
var max = data.GetExcelSheet<Item>()!
.Where(item => item.EquipSlotCategory.Value!.Body != 0)
.Select(item => item.LevelItem.Value?.RowId)
.Where(level => level != null)
.Cast<uint>()
@ -30,7 +30,7 @@ namespace BetterPartyFinder {
internal static IEnumerable<World> WorldsOnDataCentre(DataManager data, PlayerCharacter character) {
var dcRow = character.HomeWorld.GameData.DataCenter.Row;
return data.GetExcelSheet<World>()
return data.GetExcelSheet<World>()!
.Where(world => world.IsPublic && world.DataCenter.Row == dcRow);
}
}

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

94
icon.svg Executable file
View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 135.46666 135.46667"
version="1.1"
id="svg5"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="icon.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:document-units="px"
showgrid="false"
units="px"
inkscape:zoom="0.74118967"
inkscape:cx="181.46502"
inkscape:cy="346.06526"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1592"
inkscape:window-y="32"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<rect
x="41.824652"
y="49.919746"
width="437.13507"
height="429.03998"
id="rect10864" />
<rect
x="31.031193"
y="32.380376"
width="449.27771"
height="442.5318"
id="rect6722" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
transform="scale(0.26458333)"
id="text6720"
style="fill:black;fill-opacity:1;line-height:1.25;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;white-space:pre;shape-inside:url(#rect6722)" />
<g
id="g17698">
<text
xml:space="preserve"
transform="matrix(0.63979326,0,0,0.63979326,-24.52446,-7.8796286)"
id="text10862"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect10864);fill:#ea20db;fill-opacity:1;stroke:none"><tspan
x="41.824219"
y="86.413135"
id="tspan17715">Better</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:25.5917px;line-height:1.25;font-family:sans-serif;fill:#20eaaa;fill-opacity:1;stroke:none;stroke-width:0.639792"
x="26.415565"
y="77.633308"
id="text13026"><tspan
sodipodi:role="line"
id="tspan13024"
style="stroke-width:0.639792;fill:#20eaaa;fill-opacity:1"
x="26.415565"
y="77.633308">Party</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:25.5917px;line-height:1.25;font-family:sans-serif;fill:#eade20;fill-opacity:1;stroke:none;stroke-width:0.639792"
x="50.596729"
y="106.27887"
id="text14944"><tspan
sodipodi:role="line"
id="tspan14942"
style="stroke-width:0.639792;fill:#eade20;fill-opacity:1"
x="50.596729"
y="106.27887">Finder</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB