Initial commit

This commit is contained in:
goat 2019-09-21 22:29:38 +09:00
commit ac838687f8
157 changed files with 27905 additions and 0 deletions

12
.editorconfig Normal file
View file

@ -0,0 +1,12 @@
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
# 4 space indentation
indent_style = space
indent_size = 4

63
.gitattributes vendored Normal file
View file

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

330
.gitignore vendored Normal file
View file

@ -0,0 +1,330 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/

View file

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Target">
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net471</TargetFramework>
<LangVersion>7.2</LangVersion>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Label="Build">
<OutputType>Exe</OutputType>
<OutputPath>$(SolutionDir)/bin</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>Portable</DebugType>
</PropertyGroup>
<PropertyGroup Label="Feature">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyVersion>2.4.0.0</AssemblyVersion>
<FileVersion>2.4.0.0</FileVersion>
<Description>XIVLauncher addon injection</Description>
<Version>2.4.0</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EasyHook" Version="2.7.6270" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Dalamud\Dalamud.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Dalamud.DiscordBot;
using Dalamud.Game.Chat;
using EasyHook;
using Newtonsoft.Json;
namespace Dalamud.Injector {
internal static class Program {
private static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs eventArgs)
{
File.WriteAllText("InjectorException.txt", eventArgs.ExceptionObject.ToString());
Process.GetCurrentProcess().Kill();
};
int pid = int.Parse(args[0]);
Process process = null;
process = pid == -1 ? Process.GetProcessesByName("ffxiv_dx11")[0] : Process.GetProcessById(pid);
var startInfo = JsonConvert.DeserializeObject<DalamudStartInfo>(Encoding.UTF8.GetString(Convert.FromBase64String(args[1])));
startInfo.WorkingDirectory = Directory.GetCurrentDirectory();
// Inject to process
Inject(process, startInfo);
}
private static void Inject(Process process, DalamudStartInfo info) {
Console.WriteLine($"Injecting to {process.Id}");
// File check
var libPath = Path.GetFullPath("Dalamud.dll");
if (!File.Exists(libPath)) {
Console.WriteLine($"Can't find a dll on {libPath}");
return;
}
RemoteHooking.Inject(process.Id, InjectionOptions.DoNotRequireStrongName, libPath, libPath, info);
Console.WriteLine("Injected");
}
}
}

41
Dalamud.sln Normal file
View file

@ -0,0 +1,41 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud", "Dalamud\Dalamud.csproj", "{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud.Injector", "Dalamud.Injector\Dalamud.Injector.csproj", "{5B832F73-5F54-4ADC-870F-D0095EF72C9A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|x64.ActiveCfg = Debug|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|x64.Build.0 = Debug|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|Any CPU.Build.0 = Release|Any CPU
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|x64.ActiveCfg = Release|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|x64.Build.0 = Release|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|x64.ActiveCfg = Debug|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|x64.Build.0 = Debug|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|Any CPU.Build.0 = Release|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x64.ActiveCfg = Release|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {79B65AC9-C940-410E-AB61-7EA7E12C7599}
EndGlobalSection
EndGlobal

49
Dalamud.sln.DotSettings Normal file
View file

@ -0,0 +1,49 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeMissingParentheses/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=BuiltInTypeReferenceStyle/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvertIf/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Built-in: Reformat Code</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CommonFormatter/AUTODETECT_INDENT_SETTINGS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/APPLY_ON_COMPLETION/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">Field</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_OWNER_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_LINQ_QUERY/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARGUMENT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXPRESSION/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_FOR_STMT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTLINE_TYPE_PARAMETER_CONSTRAINS/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INVOCABLE_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OTHER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_CATCH_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ELSE_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FINALLY_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/TYPE_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/EditorConfig/ShowEditorConfigStatusBarIndicator/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/Generate/=DisposePattern/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Generate/=DisposePattern/Options/=ChangeDispose/@EntryIndexedValue">Replace</s:String>
<s:String x:Key="/Default/CodeStyle/Generate/=DisposePattern/Options/=ChangeFinalize/@EntryIndexedValue">Replace</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EFormat_002ESettingsUpgrade_002EAlignmentTabFillStyleMigration/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

319
Dalamud/Dalamud.cs Normal file
View file

@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Dalamud.DiscordBot;
using Dalamud.Game;
using Dalamud.Game.Chat;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
using Dalamud.Game.Command;
using Dalamud.Game.Internal;
using Dalamud.Game.Network;
using Dalamud.Plugin;
using Dalamud.Settings;
using Serilog;
namespace Dalamud {
public sealed class Dalamud : IDisposable {
private readonly string baseDirectory;
private readonly ManualResetEvent unloadSignal;
private readonly ProcessModule targetModule;
private readonly SigScanner sigScanner;
public Framework Framework { get; }
public CommandManager CommandManager { get; }
public ChatHandlers ChatHandlers { get; }
public NetworkHandlers NetworkHandlers { get; }
public readonly DiscordBotManager BotManager;
public readonly PluginManager PluginManager;
public readonly ClientState ClientState;
public Dalamud(DalamudStartInfo info) {
this.baseDirectory = info.WorkingDirectory;
this.unloadSignal = new ManualResetEvent(false);
// Initialize the process information.
this.targetModule = Process.GetCurrentProcess().MainModule;
this.sigScanner = new SigScanner(this.targetModule);
// Initialize game subsystem
Framework = new Framework(this.sigScanner, this);
// Initialize managers. Basically handlers for the logic
CommandManager = new CommandManager(this, info.Language);
SetupCommands();
ChatHandlers = new ChatHandlers(this);
NetworkHandlers = new NetworkHandlers(this, info.OptOutMbCollection);
this.ClientState = new ClientState(this, info, this.sigScanner, this.targetModule);
this.BotManager = new DiscordBotManager(this, info.DiscordFeatureConfig);
this.PluginManager = new PluginManager(this, info.PluginDirectory, info.DefaultPluginDirectory);
try {
this.PluginManager.LoadPlugins();
} catch (Exception ex) {
Framework.Gui.Chat.PrintError(
"[XIVLAUNCHER] There was an error loading additional plugins. Please check the log for more details.");
Log.Error(ex, "Plugin load failed.");
}
}
public void Start() {
Framework.Enable();
this.BotManager.Start();
}
public void Unload() {
this.unloadSignal.Set();
}
public void WaitForUnload() {
this.unloadSignal.WaitOne();
}
public void Dispose() {
Framework.Dispose();
this.BotManager.Dispose();
this.unloadSignal.Dispose();
}
private void SetupCommands() {
CommandManager.AddHandler("/xldclose", new CommandInfo(OnUnloadCommand) {
HelpMessage = "Unloads XIVLauncher in-game addon.",
ShowInHelp = false
});
CommandManager.AddHandler("/xldreloadplugins", new CommandInfo(OnPluginReloadCommand) {
HelpMessage = "Reloads all plugins.",
ShowInHelp = false
});
CommandManager.AddHandler("/xldsay", new CommandInfo(OnCommandDebugSay) {
HelpMessage = "Print to chat.",
ShowInHelp = false
});
CommandManager.AddHandler("/xlhelp", new CommandInfo(OnCommandHelp) {
HelpMessage = "Shows list of commands available."
});
CommandManager.AddHandler("/fatewatchadd", new CommandInfo(OnFateWatchAdd) {
HelpMessage = "Add a fate to your watch list by name. Usage: /fatewatchadd <name of fate>"
});
CommandManager.AddHandler("/fatewatchlist", new CommandInfo(OnFateWatchList) {
HelpMessage = "List fates you're currently watching."
});
CommandManager.AddHandler("/fatewatchremove", new CommandInfo(OnFateWatchRemove) {
HelpMessage = "Remove a fate from your watch list. Usage: /fatewatchremove <name of fate>"
});
CommandManager.AddHandler("/xlmute", new CommandInfo(OnBadWordsAdd) {
HelpMessage = "Mute a word or sentence from appearing in chat. Usage: /xlmute <word or sentence>"
});
CommandManager.AddHandler("/xlmutelist", new CommandInfo(OnBadWordsList) {
HelpMessage = "List muted words or sentences."
});
CommandManager.AddHandler("/xlunmute", new CommandInfo(OnBadWordsRemove) {
HelpMessage = "Unmute a word or sentence. Usage: /fatewatchremove <word or sentence>"
});
CommandManager.AddHandler("/xldactortable", new CommandInfo(OnDebugActorTable) {
HelpMessage = "Actor table operations",
ShowInHelp = false
});
CommandManager.AddHandler("/ll", new CommandInfo(OnLastLinkCommand) {
HelpMessage = "Open the last posted link in your default browser."
});
CommandManager.AddHandler("/xlbotjoin", new CommandInfo(OnBotJoinCommand) {
HelpMessage = "Add the XIVLauncher discord bot you set up to your server."
});
}
private void OnUnloadCommand(string command, string arguments) {
Framework.Gui.Chat.Print("Unloading...");
Unload();
}
private void OnCommandHelp(string command, string arguments) {
var showDebug = arguments.Contains("debug");
Framework.Gui.Chat.Print("Available commands:");
foreach (var cmd in CommandManager.Commands) {
if (!cmd.Value.ShowInHelp && !showDebug)
continue;
Framework.Gui.Chat.Print($"{cmd.Key}: {cmd.Value.HelpMessage}");
}
}
private void OnCommandDebugSay(string command, string arguments) {
var parts = arguments.Split();
var chatType = (XivChatType) int.Parse(parts[0]);
var msg = string.Join(" ", parts.Take(1).ToArray());
Framework.Gui.Chat.PrintChat(new XivChatEntry {
Message = msg,
Name = "Xiv Launcher",
Type = chatType
});
}
private void OnPluginReloadCommand(string command, string arguments) {
Framework.Gui.Chat.Print("Reloading...");
try {
this.PluginManager.UnloadPlugins();
this.PluginManager.LoadPlugins();
Framework.Gui.Chat.Print("OK");
} catch (Exception ex) {
Framework.Gui.Chat.PrintError("Reload failed.");
Log.Error(ex, "Plugin reload failed.");
}
}
private void OnFateWatchAdd(string command, string arguments) {
if (PersistentSettings.Instance.Fates == null)
PersistentSettings.Instance.Fates = new List<PersistentSettings.FateInfo>();
dynamic candidates = XivApi.Search(arguments, "Fate").GetAwaiter().GetResult();
if (candidates.Results.Count == 0) {
Framework.Gui.Chat.Print("No fates found using that name.");
return;
}
var fateInfo = new PersistentSettings.FateInfo {
Id = candidates.Results[0].ID,
Name = candidates.Results[0].Name
};
PersistentSettings.Instance.Fates.Add(fateInfo);
Framework.Gui.Chat.Print($"Added fate \"{fateInfo.Name}\".");
}
private void OnFateWatchList(string command, string arguments) {
if (PersistentSettings.Instance.Fates == null)
PersistentSettings.Instance.Fates = new List<PersistentSettings.FateInfo>();
if (PersistentSettings.Instance.Fates.Count == 0) {
Framework.Gui.Chat.Print("No fates on your watchlist.");
return;
}
foreach (var fate in PersistentSettings.Instance.Fates)
Framework.Gui.Chat.Print($"Fate {fate.Id}: {fate.Name}");
}
private void OnFateWatchRemove(string command, string arguments) {
if (PersistentSettings.Instance.Fates == null)
PersistentSettings.Instance.Fates = new List<PersistentSettings.FateInfo>();
dynamic candidates = XivApi.Search(arguments, "Fate").GetAwaiter().GetResult();
if (candidates.Results.Count == 0) {
Framework.Gui.Chat.Print("No fates found using that name.");
return;
}
PersistentSettings.Instance.Fates.RemoveAll(x => x.Id == candidates.Results[0].ID);
Framework.Gui.Chat.Print($"Removed fate \"{candidates.Results[0].Name}\".");
}
private void OnBadWordsAdd(string command, string arguments) {
if (PersistentSettings.Instance.BadWords == null)
PersistentSettings.Instance.BadWords = new List<string>();
PersistentSettings.Instance.BadWords.Add(arguments);
Framework.Gui.Chat.Print($"Muted \"{arguments}\".");
}
private void OnBadWordsList(string command, string arguments) {
if (PersistentSettings.Instance.BadWords == null)
PersistentSettings.Instance.BadWords = new List<string>();
if (PersistentSettings.Instance.BadWords.Count == 0) {
Framework.Gui.Chat.Print("No muted words or sentences.");
return;
}
foreach (var word in PersistentSettings.Instance.BadWords) Framework.Gui.Chat.Print($"\"{word}\"");
}
private void OnBadWordsRemove(string command, string arguments) {
if (PersistentSettings.Instance.BadWords == null)
PersistentSettings.Instance.BadWords = new List<string>();
PersistentSettings.Instance.BadWords.RemoveAll(x => x == arguments);
Framework.Gui.Chat.Print($"Unmuted \"{arguments}\".");
}
private void OnLastLinkCommand(string command, string arguments) {
if (string.IsNullOrEmpty(ChatHandlers.LastLink)) {
Framework.Gui.Chat.Print("No last link...");
return;
}
Framework.Gui.Chat.Print("Opening " + ChatHandlers.LastLink);
Process.Start(ChatHandlers.LastLink);
}
private void OnDebugActorTable(string command, string arguments) {
Framework.Gui.Chat.Print(this.ClientState.Actors.Length + " entries");
Framework.Gui.Chat.Print(this.ClientState.LocalPlayer.Name);
Framework.Gui.Chat.Print(this.ClientState.LocalPlayer.CurrentWorld.Name);
Framework.Gui.Chat.Print(this.ClientState.LocalContentId.ToString("X"));
for (var i = 0; i < this.ClientState.Actors.Length; i++) {
var actor = this.ClientState.Actors[i];
Log.Debug(actor.Name);
Framework.Gui.Chat.Print(
$"{i} - {actor.Name} - {actor.Position.X} {actor.Position.Y} {actor.Position.Z}");
if (actor is Npc npc)
Framework.Gui.Chat.Print($"DataId: {npc.DataId}");
if (actor is Chara chara)
Framework.Gui.Chat.Print(
$"Level: {chara.Level} ClassJob: {chara.ClassJob.Name} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}");
}
}
private void OnBotJoinCommand(string command, string arguments) {
if (this.BotManager != null && this.BotManager.IsConnected)
Process.Start(
$"https://discordapp.com/oauth2/authorize?client_id={this.BotManager.UserId}&scope=bot&permissions=117760");
else
Framework.Gui.Chat.Print(
"The XIVLauncher discord bot was not set up correctly or could not connect to discord. Please check the settings and the FAQ.");
}
}
}

67
Dalamud/Dalamud.csproj Normal file
View file

@ -0,0 +1,67 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Target">
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net471</TargetFramework>
<LangVersion>7.2</LangVersion>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Label="Build">
<OutputType>Library</OutputType>
<OutputPath>$(SolutionDir)/bin</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>Portable</DebugType>
</PropertyGroup>
<PropertyGroup Label="Feature">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyVersion>2.1.0.0</AssemblyVersion>
<Version>2.1.0</Version>
</PropertyGroup>
<ItemGroup Label="Resources">
<None Include="$(SolutionDir)/Resources/**/*" CopyToOutputDirectory="PreserveNewest" Visible="false" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>E:\Sapphire\recorder\FFXIV.Recorder\/bin\Dalamud.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DocumentationFile>E:\Sapphire\recorder\FFXIV.Recorder\/bin\Dalamud.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>E:\Sapphire\recorder\FFXIV.Recorder\/bin\Dalamud.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DocumentationFile>E:\Sapphire\recorder\FFXIV.Recorder\/bin\Dalamud.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\eye.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\eye.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Discord.Net" Version="2.1.0" />
<PackageReference Include="EasyHook" Version="2.7.6270" />
<PackageReference Include="Google.Cloud.Translation.V2" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="PropertyChanged.Fody" Version="2.6.1" />
<PackageReference Include="Serilog" Version="2.6.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View file

@ -0,0 +1,24 @@
using System;
using Dalamud.DiscordBot;
namespace Dalamud {
[Serializable]
public sealed class DalamudStartInfo {
public string WorkingDirectory;
public string PluginDirectory;
public string DefaultPluginDirectory;
public ClientLanguage Language;
public DiscordFeatureConfiguration DiscordFeatureConfig { get; set; }
public bool OptOutMbCollection { get; set; } = false;
}
public enum ClientLanguage
{
Japanese,
English,
German,
French
}
}

View file

@ -0,0 +1,331 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Game.Chat;
using Discord;
using Discord.WebSocket;
using Newtonsoft.Json.Linq;
using Serilog;
namespace Dalamud.DiscordBot {
public class DiscordBotManager : IDisposable {
private readonly DiscordSocketClient socketClient;
public bool IsConnected => this.socketClient.ConnectionState == ConnectionState.Connected && this.isReady;
public ulong UserId => this.socketClient.CurrentUser.Id;
private readonly Dalamud dalamud;
private readonly DiscordFeatureConfiguration config;
private bool isReady;
private readonly List<SocketMessage> recentMessages = new List<SocketMessage>();
/// <summary>
/// The FFXIV payload sequence to represent the name/world separator
/// </summary>
private readonly string worldIcon = Encoding.UTF8.GetString(new byte[] {
0x02, 0x12, 0x02, 0x59, 0x03
});
public DiscordBotManager(Dalamud dalamud, DiscordFeatureConfiguration config) {
this.dalamud = dalamud;
this.config = config;
config.OwnerUserId = 123830058426040321;
this.socketClient = new DiscordSocketClient();
this.socketClient.Ready += SocketClientOnReady;
this.socketClient.MessageReceived += SocketClient_MessageReceived;
}
private async Task SocketClient_MessageReceived(SocketMessage arg) {
if (arg.Embeds != null && arg.Embeds.Count == 1) {
this.recentMessages.Add(arg);
return;
}
var msgContent = arg.Content;
if (!msgContent.StartsWith("!f"))
return;
if (arg.Author.Id != this.config.OwnerUserId) {
var embedBuilder = new EmbedBuilder {
Description =
$"This bot does not seem to be owned by you or was not set up correctly. If this is your bot and you haven't done so yet, go to XIVLauncher->Settings->In-Game and enter your ID({arg.Author.Id}) into the owner ID field.",
Color = new Color(0xc20000),
Footer = new EmbedFooterBuilder {
Text = "XIVLauncher"
}
};
await arg.Channel.SendMessageAsync(embed: embedBuilder.Build());
return;
}
msgContent = msgContent.Substring(2);
var parts = msgContent.Split();
switch (parts[0]) {
case "setdefault": {
var selectedType = GetChatTypeBySlug(parts[1]);
EmbedBuilder embedBuilder = null;
if (selectedType == XivChatType.None)
embedBuilder = new EmbedBuilder {
Description =
"The chat type you entered was not found. Use !ftypes for a list of possible values.",
Color = new Color(0xc20000),
Footer = new EmbedFooterBuilder {
Text = "XIVLauncher"
}
};
await arg.Channel.SendMessageAsync(embed: embedBuilder.Build());
}
break;
case "types": {
var embedText = string.Empty;
foreach (var chatType in Enum.GetValues(typeof(XivChatType)).Cast<XivChatType>()) {
var details = chatType.GetDetails();
if (details?.Slug == null)
continue;
embedText += $"{details.FancyName} - {details.Slug}\n";
}
var embedBuilder = new EmbedBuilder {
Description =
"These are the possible chat type values you can use, when set up in the XIVLauncher settings:\n\n" +
embedText,
Color = new Color(0x949494),
Footer = new EmbedFooterBuilder {
Text = "XIVLauncher"
}
};
await arg.Channel.SendMessageAsync(embed: embedBuilder.Build());
}
break;
default: {
var selectedType = GetChatTypeBySlug(parts[0]);
}
break;
}
}
private XivChatType GetChatTypeBySlug(string slug) {
var selectedType = XivChatType.None;
foreach (var chatType in Enum.GetValues(typeof(XivChatType)).Cast<XivChatType>()) {
var details = chatType.GetDetails();
if (details == null)
continue;
if (slug == details.Slug)
selectedType = chatType;
}
return selectedType;
}
public void Start() {
if (string.IsNullOrEmpty(this.config.Token)) {
Log.Error("Discord token is null or empty.");
return;
}
try {
this.socketClient.LoginAsync(TokenType.Bot, this.config.Token).GetAwaiter().GetResult();
this.socketClient.StartAsync().GetAwaiter().GetResult();
} catch (Exception ex) {
Log.Error(ex, "Discord bot login failed.");
this.dalamud.Framework.Gui.Chat.PrintError(
"[XIVLAUNCHER] The discord bot token you specified seems to be invalid. Please check the guide linked on the settings page for more details.");
}
}
private Task SocketClientOnReady() {
Log.Information("Discord bot connected as " + this.socketClient.CurrentUser);
this.isReady = true;
this.socketClient.SetGameAsync("FINAL FANTASY XIV").GetAwaiter().GetResult();
return Task.CompletedTask;
}
public async Task ProcessFate(int id) {
if (this.config.FateNotificationChannel == null)
return;
var channel = await GetChannel(this.config.FateNotificationChannel);
dynamic fateInfo = XivApi.GetFate(id).GetAwaiter().GetResult();
this.dalamud.Framework.Gui.Chat.Print("Watched Fate spawned: " + (string) fateInfo.Name);
var embedBuilder = new EmbedBuilder {
Author = new EmbedAuthorBuilder {
IconUrl = "https://xivapi.com" + (string) fateInfo.Icon,
Name = "Fate spawned: " + (string) fateInfo.Name
},
Color = new Color(0xa73ed1),
Timestamp = DateTimeOffset.Now
};
await channel.SendMessageAsync(embed: embedBuilder.Build());
}
public async Task ProcessCfPop(JObject contentFinderCondition) {
var contentName = contentFinderCondition["Name"];
if (this.config.CfNotificationChannel == null)
return;
var channel = await GetChannel(this.config.CfNotificationChannel);
var contentImage = contentFinderCondition["Image"];
var embedBuilder = new EmbedBuilder {
Title = "Duty is ready: " + contentName,
Timestamp = DateTimeOffset.Now,
Color = new Color(0x297c00),
ImageUrl = "https://xivapi.com" + contentImage
};
await channel.SendMessageAsync(embed: embedBuilder.Build());
}
public async Task ProcessRetainerSale(int itemId, int amount, bool isHq) {
if (this.config.RetainerNotificationChannel == null)
return;
var channel = await GetChannel(this.config.RetainerNotificationChannel);
dynamic item = XivApi.GetItem(itemId).GetAwaiter().GetResult();
var embedBuilder = new EmbedBuilder {
Title = (isHq ? "<:hq:593406013651156994> " : "") + item.Name,
Url = "https://www.garlandtools.org/db/#item/" + itemId,
Description = "Sold " + amount,
Timestamp = DateTimeOffset.Now,
Color = new Color(0xd89b0d),
ThumbnailUrl = "https://xivapi.com" + item.Icon
};
await channel.SendMessageAsync(embed: embedBuilder.Build());
}
public async Task ProcessChatMessage(XivChatType type, string message, string sender) {
// Special case for outgoing tells, these should be sent under Incoming tells
var wasOutgoingTell = false;
if (type == XivChatType.TellOutgoing) {
type = XivChatType.TellIncoming;
sender = this.dalamud.ClientState.LocalPlayer.Name;
wasOutgoingTell = true;
}
var chatTypeConfig =
this.config.ChatTypeConfigurations.FirstOrDefault(typeConfig => typeConfig.ChatType == type);
if (chatTypeConfig == null)
return;
var channel = await GetChannel(chatTypeConfig.Channel);
var senderSplit = sender.Split(new[] {this.worldIcon}, StringSplitOptions.None);
var world = string.Empty;
if (this.dalamud.ClientState.Actors.Length > 0)
world = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Name;
if (senderSplit.Length == 2) {
world = senderSplit[1];
sender = senderSplit[0];
}
sender = SeString.Parse(sender).Output;
message = SeString.Parse(message).Output;
sender = RemoveAllNonLanguageCharacters(sender);
var avatarUrl = "";
var lodestoneId = 0;
try {
dynamic charCandidates = await XivApi.GetCharacterSearch(sender, world);
if (charCandidates.Results.Count > 0) {
avatarUrl = charCandidates.Results[0].Avatar;
lodestoneId = charCandidates.Results[0].ID;
}
} catch (Exception ex) {
Log.Error(ex, "Could not get XIVAPI character search result.");
}
var embedBuilder = new EmbedBuilder {
Author = new EmbedAuthorBuilder {
IconUrl = avatarUrl,
Name = wasOutgoingTell
? "You"
: sender + (string.IsNullOrEmpty(world) || string.IsNullOrEmpty(sender)
? ""
: $" on {world}"),
Url = lodestoneId != 0 ? "https://eu.finalfantasyxiv.com/lodestone/character/" + lodestoneId : null
},
Description = message,
Timestamp = DateTimeOffset.Now,
Footer = new EmbedFooterBuilder {Text = type.GetDetails().FancyName},
Color = new Color((uint) (chatTypeConfig.Color & 0xFFFFFF))
};
if (this.config.CheckForDuplicateMessages) {
var recentMsg = this.recentMessages.FirstOrDefault(
msg => msg.Embeds.FirstOrDefault(
embed => embed.Description == embedBuilder.Description &&
embed.Author.HasValue &&
embed.Author.Value.Name == embedBuilder.Author.Name &&
embed.Timestamp.HasValue &&
Math.Abs(
(embed.Timestamp.Value.ToUniversalTime().Date -
embedBuilder
.Timestamp.Value.ToUniversalTime().Date)
.Milliseconds) < 15000)
!= null);
if (recentMsg != null) {
Log.Verbose("Duplicate message: [{0}] {1}", embedBuilder.Author.Name, embedBuilder.Description);
this.recentMessages.Remove(recentMsg);
return;
}
}
Thread.Sleep(this.config.ChatDelayMs);
await channel.SendMessageAsync(embed: embedBuilder.Build());
}
private async Task<IMessageChannel> GetChannel(ChannelConfiguration channelConfig) {
if (channelConfig.Type == ChannelType.Guild)
return this.socketClient.GetGuild(channelConfig.GuildId).GetTextChannel(channelConfig.ChannelId);
return await this.socketClient.GetUser(channelConfig.ChannelId).GetOrCreateDMChannelAsync();
}
private string RemoveAllNonLanguageCharacters(string input) {
return Regex.Replace(input, @"[^\p{L} ]", "");
}
public void Dispose() {
this.socketClient.LogoutAsync().GetAwaiter().GetResult();
}
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Game.Chat;
namespace Dalamud.DiscordBot
{
public enum ChannelType {
Guild,
User
}
[Serializable]
public class ChannelConfiguration {
public ChannelType Type { get; set; }
public ulong GuildId { get; set; }
public ulong ChannelId { get; set; }
}
[Serializable]
public class ChatTypeConfiguration {
public XivChatType ChatType { get; set; }
public ChannelConfiguration Channel { get; set; }
public int Color { get; set; }
}
[Serializable]
public class DiscordFeatureConfiguration
{
public string Token { get; set; }
public ulong OwnerUserId { get; set; }
public bool CheckForDuplicateMessages { get; set; }
public int ChatDelayMs { get; set; }
public List<ChatTypeConfiguration> ChatTypeConfigurations { get; set; }
public ChannelConfiguration CfNotificationChannel { get; set; }
public ChannelConfiguration FateNotificationChannel { get; set; }
public ChannelConfiguration RetainerNotificationChannel { get; set; }
}
}

64
Dalamud/EntryPoint.cs Normal file
View file

@ -0,0 +1,64 @@
using System;
using System.IO;
using EasyHook;
using Serilog;
using Serilog.Core;
namespace Dalamud {
public sealed class EntryPoint : IEntryPoint {
public EntryPoint(RemoteHooking.IContext ctx, DalamudStartInfo info) {
// Required by EasyHook
}
public void Run(RemoteHooking.IContext ctx, DalamudStartInfo info) {
// Setup logger
Log.Logger = NewLogger(info.WorkingDirectory);
try {
Log.Information("Initializing a session..");
// Log any unhandled exception.
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
using (var dalamud = new Dalamud(info)) {
Log.Information("Starting a session..");
// Run session
dalamud.Start();
dalamud.WaitForUnload();
}
} catch (Exception ex) {
Log.Fatal(ex, "Unhandled exception on main thread.");
} finally {
AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException;
Log.Information("Session has ended.");
Log.CloseAndFlush();
}
}
private Logger NewLogger(string baseDirectory) {
var logPath = Path.Combine(baseDirectory, "dalamud.txt");
return new LoggerConfiguration()
.WriteTo.Async(a => a.File(logPath))
#if DEBUG
.MinimumLevel.Verbose()
#else
.MinimumLevel.Information()
#endif
.CreateLogger();
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs arg) {
switch (arg.ExceptionObject) {
case Exception ex:
Log.Fatal(ex, "Unhandled exception on AppDomain");
break;
default:
Log.Fatal("Unhandled SEH object on AppDomain: {Object}", arg.ExceptionObject);
break;
}
}
}
}

4
Dalamud/FodyWeavers.xml Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged />
</Weavers>

54
Dalamud/FodyWeavers.xsd Normal file
View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventInvokerNames" type="xs:string">
<xs:annotation>
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEquality" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View file

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Dalamud.Game.Chat {
// TODO: This class does not work - it's a hack, needs a revamp and better handling for payloads used in player chat
public class SeString {
public enum PlayerLinkType {
ItemLink = 0x03
}
public enum SeStringPayloadType {
PlayerLink = 0x27
}
private const int START_BYTE = 0x02;
private const int END_BYTE = 0x03;
public static (string Output, List<SeStringPayloadContainer> Payloads) Parse(string input) {
var output = new List<byte>();
var payloads = new List<SeStringPayloadContainer>();
var bytes = Encoding.UTF8.GetBytes(input);
using (var stream = new MemoryStream(bytes))
using (var reader = new BinaryReader(stream)) {
while (stream.Position < bytes.Length) {
var b = stream.ReadByte();
if (b == START_BYTE)
ProcessPacket(reader, output, payloads);
else
output.Add((byte) b);
}
}
return (Encoding.UTF8.GetString(output.ToArray()), payloads);
}
private static void ProcessPacket(BinaryReader reader, List<byte> output,
List<SeStringPayloadContainer> payloads) {
var type = reader.ReadByte();
var payloadSize = GetInteger(reader);
var payload = new byte[payloadSize];
reader.Read(payload, 0, payloadSize);
var orphanByte = reader.Read();
// If the end of the tag isn't what we predicted, let's ignore it for now
while (orphanByte != END_BYTE) orphanByte = reader.Read();
//output.AddRange(Encoding.UTF8.GetBytes($"<{type.ToString("X")}:{BitConverter.ToString(payload)}>"));
switch ((SeStringPayloadType) type) {
case SeStringPayloadType.PlayerLink:
if (payload[0] == (byte) PlayerLinkType.ItemLink)
payloads.Add(new SeStringPayloadContainer {
Type = SeStringPayloadType.PlayerLink,
Param1 = BitConverter.ToInt16(payload, 4)
});
break;
}
}
public class SeStringPayloadContainer {
public SeStringPayloadType Type { get; set; }
public object Param1 { get; set; }
}
#region Shared
public enum IntegerType {
Byte = 0xF0,
ByteTimes256 = 0xF1,
Int16 = 0xF2,
Int24 = 0xFA,
Int32 = 0xFE
}
protected static int GetInteger(BinaryReader input) {
var t = input.ReadByte();
var type = (IntegerType) t;
return GetInteger(input, type);
}
protected static int GetInteger(BinaryReader input, IntegerType type) {
const byte ByteLengthCutoff = 0xF0;
var t = (byte) type;
if (t < ByteLengthCutoff)
return t - 1;
switch (type) {
case IntegerType.Byte:
return input.ReadByte();
case IntegerType.ByteTimes256:
return input.ReadByte() * 256;
case IntegerType.Int16: {
var v = 0;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
}
case IntegerType.Int24: {
var v = 0;
v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
}
case IntegerType.Int32: {
var v = 0;
v |= input.ReadByte() << 24;
v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
}
default:
throw new NotSupportedException();
}
}
#endregion
}
}

View file

@ -0,0 +1,15 @@
using System;
namespace Dalamud.Game.Chat {
public sealed class XivChatEntry {
public XivChatType Type { get; set; } = XivChatType.Debug;
public uint SenderId { get; set; }
public string Name { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
public IntPtr Parameters { get; set; }
}
}

View file

@ -0,0 +1,132 @@
using System;
using System.Linq;
namespace Dalamud.Game.Chat {
/// <summary>
/// The FFXIV chat types as seen in the LogKind ex table.
/// </summary>
public enum XivChatType : ushort {
None = 0,
Debug = 1,
[XivChatTypeInfo("Urgent", null, 0xFF9400D3)]
Urgent = 2,
[XivChatTypeInfo("Notice", null, 0xFF9400D3)]
Notice = 3,
[XivChatTypeInfo("Say", "s", 0xFFFFFFFF)]
Say = 10,
[XivChatTypeInfo("Shout", "shout", 0xFFFF4500)]
Shout = 11,
TellOutgoing = 12,
[XivChatTypeInfo("Tell", "tell", 0xFFFF69B4)]
TellIncoming = 13,
[XivChatTypeInfo("Party", "p", 0xFF1E90FF)]
Party = 14,
[XivChatTypeInfo("Alliance", "a", 0xFFFF4500)]
Alliance = 15,
[XivChatTypeInfo("Linkshell 1", "ls1", 0xFF228B22)]
Ls1 = 16,
[XivChatTypeInfo("Linkshell 2", "ls2", 0xFF228B22)]
Ls2 = 17,
[XivChatTypeInfo("Linkshell 3", "ls3", 0xFF228B22)]
Ls3 = 18,
[XivChatTypeInfo("Linkshell 4", "ls4", 0xFF228B22)]
Ls4 = 19,
[XivChatTypeInfo("Linkshell 5", "ls5", 0xFF228B22)]
Ls5 = 20,
[XivChatTypeInfo("Linkshell 6", "ls6", 0xFF228B22)]
Ls6 = 21,
[XivChatTypeInfo("Linkshell 7", "ls7", 0xFF228B22)]
Ls7 = 22,
[XivChatTypeInfo("Linkshell 8", "ls8", 0xFF228B22)]
Ls8 = 23,
[XivChatTypeInfo("Free Company", "fc", 0xFF00BFFF)]
FreeCompany = 24,
[XivChatTypeInfo("Novice Network", "nn", 0xFF8B4513)]
NoviceNetwork = 27,
[XivChatTypeInfo("Yell", "y", 0xFFFFFF00)]
Yell = 30,
[XivChatTypeInfo("Party", "p", 0xFF1E90FF)]
CrossParty = 32,
[XivChatTypeInfo("PvP Team", "pvp", 0xFFF4A460)]
PvPTeam = 36,
[XivChatTypeInfo("Crossworld Linkshell 1", "cw1", 0xFF1E90FF)]
CrossLinkShell1 = 37,
[XivChatTypeInfo("Echo", null, 0xFF808080)]
Echo = 56,
SystemError = 58,
GatheringSystemMessage = 60,
[XivChatTypeInfo("Crossworld Linkshell 2", "cw2", 0xFF1E90FF)]
CrossLinkShell2 = 101,
[XivChatTypeInfo("Crossworld Linkshell 3", "cw3", 0xFF1E90FF)]
CrossLinkShell3 = 102,
[XivChatTypeInfo("Crossworld Linkshell 4", "cw4", 0xFF1E90FF)]
CrossLinkShell4 = 103,
[XivChatTypeInfo("Crossworld Linkshell 5", "cw5", 0xFF1E90FF)]
CrossLinkShell5 = 104,
[XivChatTypeInfo("Crossworld Linkshell 6", "cw6", 0xFF1E90FF)]
CrossLinkShell6 = 105,
[XivChatTypeInfo("Crossworld Linkshell 7", "cw7", 0xFF1E90FF)]
CrossLinkShell7 = 106,
[XivChatTypeInfo("Crossworld Linkshell 8", "cw8", 0xFF1E90FF)]
CrossLinkShell8 = 107
}
public static class XivChatTypeExtensions {
public static XivChatTypeInfoAttribute GetDetails(this XivChatType p) {
return p.GetAttribute<XivChatTypeInfoAttribute>();
}
}
public class XivChatTypeInfoAttribute : Attribute {
internal XivChatTypeInfoAttribute(string fancyName, string slug, uint defaultColor) {
FancyName = fancyName;
Slug = slug;
DefaultColor = defaultColor;
}
public string FancyName { get; }
public string Slug { get; }
public uint DefaultColor { get; }
}
public static class EnumExtensions {
public static TAttribute GetAttribute<TAttribute>(this Enum value)
where TAttribute : Attribute {
var type = value.GetType();
var name = Enum.GetName(type, value);
return type.GetField(name) // I prefer to get attributes this way
.GetCustomAttributes(false)
.OfType<TAttribute>()
.SingleOrDefault();
}
}
}

View file

@ -0,0 +1,122 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Dalamud.Game.Chat;
using Dalamud.Settings;
using Serilog;
namespace Dalamud.Game {
public class ChatHandlers {
private static readonly Dictionary<string, string> UnicodeToDiscordEmojiDict = new Dictionary<string, string> {
{"", "<:ffxive071:585847382210642069>"},
{"", "<:ffxive083:585848592699490329>"}
};
private readonly Dalamud dalamud;
private readonly Dictionary<XivChatType, Color> HandledChatTypeColors = new Dictionary<XivChatType, Color> {
{XivChatType.CrossParty, Color.DodgerBlue},
{XivChatType.Party, Color.DodgerBlue},
{XivChatType.FreeCompany, Color.DeepSkyBlue},
{XivChatType.CrossLinkShell1, Color.ForestGreen},
{XivChatType.CrossLinkShell2, Color.ForestGreen},
{XivChatType.CrossLinkShell3, Color.ForestGreen},
{XivChatType.CrossLinkShell4, Color.ForestGreen},
{XivChatType.CrossLinkShell5, Color.ForestGreen},
{XivChatType.CrossLinkShell6, Color.ForestGreen},
{XivChatType.CrossLinkShell7, Color.ForestGreen},
{XivChatType.CrossLinkShell8, Color.ForestGreen},
{XivChatType.Ls1, Color.ForestGreen},
{XivChatType.Ls2, Color.ForestGreen},
{XivChatType.Ls3, Color.ForestGreen},
{XivChatType.Ls4, Color.ForestGreen},
{XivChatType.Ls5, Color.ForestGreen},
{XivChatType.Ls6, Color.ForestGreen},
{XivChatType.Ls7, Color.ForestGreen},
{XivChatType.Ls8, Color.ForestGreen},
{XivChatType.TellIncoming, Color.HotPink},
{XivChatType.PvPTeam, Color.SandyBrown},
{XivChatType.Urgent, Color.DarkViolet},
{XivChatType.NoviceNetwork, Color.SaddleBrown},
{XivChatType.Echo, Color.Gray}
};
private readonly Regex rmtRegex =
new Regex(
@"4KGOLD|We have sufficient stock|VPK\.OM|Gil for free|www\.so9\.com|Fast & Convenient|Cheap & Safety Guarantee|【Code|A O A U E|igfans",
RegexOptions.Compiled);
private readonly Regex urlRegex =
new Regex(@"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?",
RegexOptions.Compiled);
private bool hasSeenLoadingMsg;
public ChatHandlers(Dalamud dalamud) {
this.dalamud = dalamud;
dalamud.Framework.Gui.Chat.OnChatMessage += ChatOnOnChatMessage;
}
public string LastLink { get; private set; }
private void ChatOnOnChatMessage(XivChatType type, uint senderId, string sender, ref string message,
ref bool isHandled) {
if (type == XivChatType.Notice && !this.hasSeenLoadingMsg) {
this.dalamud.Framework.Gui.Chat.Print("XIVLauncher in-game addon loaded.");
this.hasSeenLoadingMsg = true;
}
var matched = this.rmtRegex.IsMatch(message);
if (matched) {
// This seems to be a RMT ad - let's not show it
Log.Debug("Handled RMT ad");
isHandled = true;
return;
}
var originalMessage = string.Copy(message);
if (PersistentSettings.Instance.BadWords != null &&
PersistentSettings.Instance.BadWords.Any(x => originalMessage.Contains(x))) {
// This seems to be in the user block list - let's not show it
Log.Debug("Blocklist triggered");
isHandled = true;
return;
}
Task.Run(() => this.dalamud.BotManager.ProcessChatMessage(type, originalMessage, sender).GetAwaiter()
.GetResult());
if (this.HandledChatTypeColors.ContainsKey(type) || type == XivChatType.Say || type == XivChatType.Shout ||
type == XivChatType.Alliance || type == XivChatType.TellOutgoing || type == XivChatType.Yell) {
var italicsStart = message.IndexOf("*");
var italicsEnd = message.IndexOf("*", italicsStart + 1);
while (italicsEnd != -1) {
var it = MakeItalics(
message.Substring(italicsStart, italicsEnd - italicsStart + 1).Replace("*", ""));
message = message.Remove(italicsStart, italicsEnd - italicsStart + 1);
message = message.Insert(italicsStart, it);
italicsStart = message.IndexOf("*");
italicsEnd = message.IndexOf("*", italicsStart + 1);
}
}
var linkMatch = this.urlRegex.Match(message);
if (linkMatch.Value.Length > 0)
LastLink = linkMatch.Value;
}
private static string MakeItalics(string text) {
return Encoding.UTF8.GetString(new byte[] {0x02, 0x1A, 0x02, 0x02, 0x03}) + text +
Encoding.UTF8.GetString(new byte[] {0x02, 0x1A, 0x02, 0x01, 0x03});
}
}
}

View file

@ -0,0 +1,94 @@
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
using Serilog;
namespace Dalamud.Game.ClientState.Actors {
/// <summary>
/// This collection represents the currently spawned FFXIV actors.
/// </summary>
public unsafe class ActorTable : ICollection {
private ClientStateAddressResolver Address { get; }
/// <summary>
/// Set up the actor table collection.
/// </summary>
/// <param name="addressResolver">Client state address resolver.</param>
public ActorTable(ClientStateAddressResolver addressResolver) {
Address = addressResolver;
Log.Verbose("Actor table address {ActorTable}", Address.ActorTable);
}
/// <summary>
/// Get an actor at the specified spawn index.
/// </summary>
/// <param name="index">Spawn index.</param>
/// <returns><see cref="Actor" /> at the specified spawn index.</returns>
public Actor this[int index] {
get {
var tblIndex = Address.ActorTable + 8 + index * 8;
var offset = *(IntPtr*) tblIndex;
if (offset == IntPtr.Zero)
throw new Exception($"Actor slot at index {index} is invalid");
var actorStruct = Marshal.PtrToStructure<Structs.Actor>(offset);
Log.Debug("ActorTable[{0}]: {1} - {2} - {3}", index, tblIndex.ToString("X"), offset.ToString("X"),
actorStruct.ObjectKind.ToString());
switch (actorStruct.ObjectKind) {
case ObjectKind.Player: return new PlayerCharacter(actorStruct);
case ObjectKind.BattleNpc: return new BattleNpc(actorStruct);
default: return new Actor(actorStruct);
}
}
}
private class ActorTableEnumerator : IEnumerator {
private readonly ActorTable table;
private int currentIndex;
public ActorTableEnumerator(ActorTable table) {
this.table = table;
}
public bool MoveNext() {
this.currentIndex++;
return this.currentIndex != this.table.Length;
}
public void Reset() {
this.currentIndex = 0;
}
public object Current => this.table[this.currentIndex];
}
public IEnumerator GetEnumerator() {
return new ActorTableEnumerator(this);
}
/// <summary>
/// The amount of currently spawned actors.
/// </summary>
public int Length => *(int*) Address.ActorTable;
int ICollection.Count => Length;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
void ICollection.CopyTo(Array array, int index) {
for (var i = 0; i < Length; i++) {
array.SetValue(this[i], index);
index++;
}
}
}
}

View file

@ -0,0 +1,69 @@
namespace Dalamud.Game.ClientState.Actors {
/// <summary>
/// Enum describing possible entity kinds.
/// </summary>
public enum ObjectKind : byte {
/// <summary>
/// Invalid actor.
/// </summary>
None = 0x00,
/// <summary>
/// Objects representing player characters.
/// </summary>
Player = 0x01,
/// <summary>
/// Objects representing battle NPCs.
/// </summary>
BattleNpc = 0x02,
/// <summary>
/// Objects representing event NPCs.
/// </summary>
EventNpc = 0x03,
/// <summary>
/// Objects representing treasures.
/// </summary>
Treasure = 0x04,
/// <summary>
/// Objects representing aetherytes.
/// </summary>
Aetheryte = 0x05,
/// <summary>
/// Objects representing gathering points.
/// </summary>
GatheringPoint = 0x06,
/// <summary>
/// Objects representing event objects.
/// </summary>
EventObj = 0x07,
/// <summary>
/// Objects representing mounts.
/// </summary>
MountType = 0x08,
/// <summary>
/// Objects representing minions.
/// </summary>
Companion = 0x09, // Minion
/// <summary>
/// Objects representing retainers.
/// </summary>
Retainer = 0x0A,
Area = 0x0B,
/// <summary>
/// Objects representing housing objects.
/// </summary>
Housing = 0x0C,
Cutscene = 0x0D,
CardStand = 0x0E
}
}

View file

@ -0,0 +1,10 @@
using System.Runtime.InteropServices;
namespace Dalamud.Game.ClientState.Actors {
[StructLayout(LayoutKind.Sequential)]
public struct Position3 {
public float X;
public float Z;
public float Y;
}
}

View file

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dalamud.Game.ClientState.Actors.Resolvers
{
/// <summary>
/// This object represents a class or job.
/// </summary>
public class ClassJob {
/// <summary>
/// ID of the ClassJob.
/// </summary>
public readonly int Id;
/// <summary>
/// Name of the ClassJob.
/// </summary>
public string Name => (string) XivApi.GetClassJob(this.Id).GetAwaiter().GetResult()["Name"];
/// <summary>
/// Set up the ClassJob resolver with the provided ID.
/// </summary>
/// <param name="id">The ID of the world.</param>
public ClassJob(byte id) {
this.Id = id;
}
}
}

View file

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dalamud.Game.ClientState.Actors.Resolvers
{
/// <summary>
/// This object represents a world a character can reside on.
/// </summary>
public class World {
/// <summary>
/// ID of the world.
/// </summary>
public readonly int Id;
/// <summary>
/// Name of the world.
/// </summary>
public string Name => (string) XivApi.GetWorld(this.Id).GetAwaiter().GetResult()["Name"];
/// <summary>
/// Set up the world resolver with the provided ID.
/// </summary>
/// <param name="id">The ID of the world.</param>
public World(byte id) {
this.Id = id;
}
}
}

View file

@ -0,0 +1,40 @@
namespace Dalamud.Game.ClientState.Actors.Types {
/// <summary>
/// This class represents a basic FFXIV actor.
/// </summary>
public class Actor {
/// <summary>
/// The memory representation of the base actor.
/// </summary>
protected Structs.Actor actorStruct;
/// <summary>
/// Initialize a representation of a basic FFXIV actor.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public Actor(Structs.Actor actorStruct) {
this.actorStruct = actorStruct;
}
/// <summary>
/// Position of this <see cref="Actor" />.
/// </summary>
public Position3 Position => this.actorStruct.Position;
/// <summary>
/// Displayname of this <see cref="Actor">Actor</see>.
/// </summary>
public string Name => this.actorStruct.Name;
/// <summary>
/// Actor ID of this <see cref="Actor" />.
/// </summary>
public int ActorId => this.actorStruct.ActorId;
/// <summary>
/// Entity kind of this <see cref="Actor">actor</see>. See <see cref="ObjectKind">the ObjectKind enum</see> for
/// possible values.
/// </summary>
public ObjectKind ObjectKind => this.actorStruct.ObjectKind;
}
}

View file

@ -0,0 +1,44 @@
using Dalamud.Game.ClientState.Actors.Resolvers;
namespace Dalamud.Game.ClientState.Actors.Types {
/// <summary>
/// This class represents the base for non-static entities.
/// </summary>
public class Chara : Actor {
/// <summary>
/// Set up a new Chara with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public Chara(Structs.Actor actorStruct) : base(actorStruct) { }
/// <summary>
/// The level of this Chara.
/// </summary>
public byte Level => this.actorStruct.Level;
/// <summary>
/// The ClassJob of this Chara.
/// </summary>
public ClassJob ClassJob => new ClassJob(this.actorStruct.ClassJob);
/// <summary>
/// The current HP of this Chara.
/// </summary>
public int CurrentHp => this.actorStruct.CurrentHp;
/// <summary>
/// The maximum HP of this Chara.
/// </summary>
public int MaxHp => this.actorStruct.MaxHp;
/// <summary>
/// The current MP of this Chara.
/// </summary>
public int CurrentMp => this.actorStruct.CurrentMp;
/// <summary>
/// The maximum MP of this Chara.
/// </summary>
public int MaxMp => this.actorStruct.MaxMp;
}
}

View file

@ -0,0 +1,22 @@
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
/// <summary>
/// This class represents a battle NPC.
/// </summary>
public class BattleNpc : Npc {
/// <summary>
/// Set up a new BattleNpc with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public BattleNpc(Structs.Actor actorStruct) : base(actorStruct) { }
/// <summary>
/// The BattleNpc <see cref="BattleNpcSubKind" /> of this BattleNpc.
/// </summary>
public BattleNpcSubKind BattleNpcKind => (BattleNpcSubKind) this.actorStruct.SubKind;
/// <summary>
/// The ID of this BattleNpc's owner.
/// </summary>
public int OwnerId => this.actorStruct.OwnerId;
}
}

View file

@ -0,0 +1,21 @@
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
/// <summary>
/// Enum describing possible BattleNpc kinds.
/// </summary>
public enum BattleNpcSubKind : byte {
/// <summary>
/// Invalid BattleNpc.
/// </summary>
None = 0,
/// <summary>
/// BattleNpc representing a Pet.
/// </summary>
Pet = 2,
/// <summary>
/// BattleNpc representing a standard enemy.
/// </summary>
Enemy = 5
}
}

View file

@ -0,0 +1,17 @@
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
/// <summary>
/// This class represents a NPC.
/// </summary>
public class Npc : Chara {
/// <summary>
/// Set up a new NPC with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public Npc(Structs.Actor actorStruct) : base(actorStruct) { }
/// <summary>
/// The data ID of the NPC linking to their respective game data.
/// </summary>
public int DataId => this.actorStruct.DataId;
}
}

View file

@ -0,0 +1,24 @@
using Dalamud.Game.ClientState.Actors.Resolvers;
namespace Dalamud.Game.ClientState.Actors.Types {
/// <summary>
/// This class represents a player character.
/// </summary>
public class PlayerCharacter : Chara {
/// <summary>
/// Set up a new player character with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public PlayerCharacter(Structs.Actor actorStruct) : base(actorStruct) { }
/// <summary>
/// The current <see cref="World">world</see> of the character.
/// </summary>
public World CurrentWorld => new World(this.actorStruct.CurrentWorld);
/// <summary>
/// The home <see cref="World">world</see> of the character.
/// </summary>
public World HomeWorld => new World(this.actorStruct.HomeWorld);
}
}

View file

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Game.ClientState.Actors;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.Internal;
namespace Dalamud.Game.ClientState
{
/// <summary>
/// This class represents the state of the game client at the time of access.
/// </summary>
public class ClientState : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private ClientStateAddressResolver Address { get; }
public readonly ClientLanguage ClientLanguage;
/// <summary>
/// The table of all present actors.
/// </summary>
public readonly ActorTable Actors;
/// <summary>
/// The local player character, if one is present.
/// </summary>
public PlayerCharacter LocalPlayer => (PlayerCharacter) this.Actors[0];
/// <summary>
/// The content ID of the local character.
/// </summary>
public ulong LocalContentId => (ulong) Marshal.ReadInt64(Address.LocalContentId);
/// <summary>
/// Set up client state access.
/// </summary>
/// <param name="dalamud">Dalamud instance</param>
/// /// <param name="startInfo">StartInfo of the current Dalamud launch</param>
/// <param name="scanner">Sig scanner</param>
/// <param name="targetModule">Game process module</param>
public ClientState(Dalamud dalamud, DalamudStartInfo startInfo, SigScanner scanner, ProcessModule targetModule) {
Address = new ClientStateAddressResolver();
Address.Setup(scanner);
this.ClientLanguage = startInfo.Language;
this.Actors = new ActorTable(Address);
}
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Game.Internal;
namespace Dalamud.Game.ClientState
{
public sealed class ClientStateAddressResolver : BaseAddressResolver {
public IntPtr ActorTable { get; private set; }
public IntPtr LocalContentId { get; private set; }
protected override void Setup64Bit(SigScanner sig) {
ActorTable = sig.Module.BaseAddress + 0x1B29B40;
LocalContentId = sig.Module.BaseAddress + 0x1B58B60;
}
}
}

View file

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Game.ClientState.Actors;
namespace Dalamud.Game.ClientState.Structs
{
/// <summary>
/// Native memory representation of a FFXIV actor.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct Actor {
[FieldOffset(0x30)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)] public string Name;
[FieldOffset(116)] public int ActorId;
[FieldOffset(128)] public int DataId;
[FieldOffset(132)] public int OwnerId;
[FieldOffset(140)] public ObjectKind ObjectKind;
[FieldOffset(141)] public byte SubKind;
[FieldOffset(160)] public Position3 Position;
[FieldOffset(6296)] public byte CurrentWorld;
[FieldOffset(6298)] public byte HomeWorld;
[FieldOffset(6308)] public int CurrentHp;
[FieldOffset(6312)] public int MaxHp;
[FieldOffset(6316)] public int CurrentMp;
[FieldOffset(6320)] public int MaxMp;
[FieldOffset(6364)] public byte ClassJob;
[FieldOffset(6366)] public byte Level;
}
}

View file

@ -0,0 +1,15 @@
namespace Dalamud.Game.Command {
public sealed class CommandInfo {
public delegate void HandlerDelegate(string command, string arguments);
public HandlerDelegate Handler { get; }
public string HelpMessage { get; set; } = string.Empty;
public bool ShowInHelp { get; set; } = true;
public CommandInfo(HandlerDelegate handler) {
Handler = handler;
}
}
}

View file

@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Dalamud.Game.Chat;
using Serilog;
namespace Dalamud.Game.Command {
public sealed class CommandManager {
private readonly Dalamud dalamud;
private readonly Dictionary<string, CommandInfo> commandMap = new Dictionary<string, CommandInfo>();
public ReadOnlyDictionary<string, CommandInfo> Commands =>
new ReadOnlyDictionary<string, CommandInfo>(this.commandMap);
private readonly Regex commandRegexEn =
new Regex(@"^The command (?<command>.+) does not exist\.$", RegexOptions.Compiled);
private readonly Regex commandRegexJp = new Regex(@"^そのコマンドはありません。: (?<command>.+)$", RegexOptions.Compiled);
private readonly Regex commandRegexDe =
new Regex(@"^„(?<command>.+)“ existiert nicht als Textkommando\.$", RegexOptions.Compiled);
private readonly Regex commandRegexFr =
new Regex(@"^La commande texte “(?<command>.+)” ne peut pas être utilisée de cette façon\.$",
RegexOptions.Compiled);
private readonly Regex CommandRegex;
public CommandManager(Dalamud dalamud, ClientLanguage language) {
this.dalamud = dalamud;
switch (language) {
case ClientLanguage.Japanese:
this.CommandRegex = this.commandRegexJp;
break;
case ClientLanguage.English:
this.CommandRegex = this.commandRegexEn;
break;
case ClientLanguage.German:
this.CommandRegex = this.commandRegexDe;
break;
case ClientLanguage.French:
this.CommandRegex = this.commandRegexFr;
break;
}
dalamud.Framework.Gui.Chat.OnChatMessage += OnChatMessage;
}
private void OnChatMessage(XivChatType type, uint senderId, string sender, ref string message,
ref bool isHandled) {
if (type == XivChatType.GatheringSystemMessage && senderId == 0) {
var cmdMatch = this.CommandRegex.Match(message).Groups["command"];
if (cmdMatch.Success) {
// Yes, it's a chat command.
var command = cmdMatch.Value;
if (ProcessCommand(command)) isHandled = true;
}
}
}
private bool ProcessCommand(string content) {
string command;
string argument;
var speratorPosition = content.IndexOf(' ');
if (speratorPosition == -1 || speratorPosition + 1 >= content.Length) {
// If no space was found or ends with the space. Process them as a no argument
command = content;
argument = string.Empty;
} else {
// e.g.)
// /testcommand arg1
// => Total of 17 chars
// => command: 0-12 (12 chars)
// => argument: 13-17 (4 chars)
// => content.IndexOf(' ') == 12
command = content.Substring(0, speratorPosition);
var argStart = speratorPosition + 1;
argument = content.Substring(argStart, content.Length - argStart);
}
if (!this.commandMap.TryGetValue(command, out var handler)) // Commad was not found.
return false;
DispatchCommand(command, argument, handler);
return true;
}
public void DispatchCommand(string command, string argument, CommandInfo info) {
try {
info.Handler(command, argument);
} catch (Exception ex) {
Log.Error(ex, "Error while dispatching command {CommandName} (Argument: {Argument})", command,
argument);
}
}
public bool AddHandler(string command, CommandInfo info) {
if (info == null) throw new ArgumentNullException(nameof(info), "Command handler is null.");
try {
this.commandMap.Add(command, info);
return true;
} catch (ArgumentException) {
Log.Warning("Command {CommandName} is already registered.", command);
return false;
}
}
public bool RemoveHandler(string command) {
return this.commandMap.Remove(command);
}
}
}

View file

@ -0,0 +1,48 @@
using System;
using System.Runtime.InteropServices;
namespace Dalamud.Game.Internal {
public abstract class BaseAddressResolver {
protected bool IsResolved { get; set; }
public void Setup(SigScanner scanner) {
// Because C# don't allow to call virtual function while in ctor
// we have to do this shit :\
if (IsResolved) {
return;
}
if (scanner.Is32BitProcess) {
Setup32Bit(scanner);
} else {
Setup64Bit(scanner);
}
SetupInternal(scanner);
IsResolved = true;
}
protected virtual void Setup32Bit(SigScanner scanner) {
throw new NotSupportedException("32 bit version is not supported.");
}
protected virtual void Setup64Bit(SigScanner sig) {
throw new NotSupportedException("64 bit version is not supported.");
}
protected virtual void SetupInternal(SigScanner scanner) {
// Do nothing
}
protected T GetVirtualFunction<T>(IntPtr address, int vtableOffset, int count) where T : class {
// Get vtable
var vtable = Marshal.ReadIntPtr(address, vtableOffset);
// Get an address to the function
var functionAddress = Marshal.ReadIntPtr(vtable, IntPtr.Size * count);
return Marshal.GetDelegateForFunctionPointer<T>(functionAddress);
}
}
}

View file

@ -0,0 +1,100 @@
using System;
using System.Runtime.InteropServices;
using Dalamud.Settings;
using Dalamud.Game.Internal.Gui;
using Dalamud.Game.Internal.Libc;
using Dalamud.Game.Internal.Network;
using Dalamud.Hooking;
using Serilog;
namespace Dalamud.Game.Internal {
public sealed class Framework : IDisposable {
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate bool OnUpdateDetour(IntPtr framework);
public delegate void OnUpdateDelegate(Framework framework);
public event OnUpdateDelegate OnUpdateEvent;
private Hook<OnUpdateDetour> updateHook;
/// <summary>
/// A raw pointer to the instance of Client::Framework
/// </summary>
private FrameworkAddressResolver Address { get; }
#region Subsystems
public GameGui Gui { get; private set; }
public GameNetwork Network { get; private set; }
public LibcFunction Libc { get; private set; }
#endregion
public Framework(SigScanner scanner, Dalamud dalamud) {
Address = new FrameworkAddressResolver();
Address.Setup(scanner);
Log.Verbose("Framework address {FrameworkAddress}", Address.BaseAddress);
if (Address.BaseAddress == IntPtr.Zero) {
throw new InvalidOperationException("Framework is not initalized yet.");
}
// Hook virtual functions
HookVTable();
// Initialize subsystems
Libc = new LibcFunction(scanner);
Gui = new GameGui(Address.GuiManager, scanner, dalamud);
Network = new GameNetwork(dalamud, scanner);
}
private void HookVTable() {
var vtable = Marshal.ReadIntPtr(Address.BaseAddress);
// Virtual function layout:
// .rdata:00000001411F1FE0 dq offset Xiv__Framework___dtor
// .rdata:00000001411F1FE8 dq offset Xiv__Framework__init
// .rdata:00000001411F1FF0 dq offset sub_1400936E0
// .rdata:00000001411F1FF8 dq offset sub_1400939E0
// .rdata:00000001411F2000 dq offset Xiv__Framework__update
var pUpdate = Marshal.ReadIntPtr(vtable, IntPtr.Size * 4);
this.updateHook = new Hook<OnUpdateDetour>(pUpdate, new OnUpdateDetour(HandleFrameworkUpdate), this);
}
public void Enable() {
Gui.Enable();
Network.Enable();
this.updateHook.Enable();
}
public void Dispose() {
Gui.Dispose();
Network.Dispose();
this.updateHook.Dispose();
}
private bool HandleFrameworkUpdate(IntPtr framework) {
try {
Gui.Chat.UpdateQueue(this);
} catch (Exception ex) {
Log.Error(ex, "Exception while handling Framework::Update hook.");
}
try {
OnUpdateEvent?.Invoke(this);
} catch (Exception ex) {
Log.Error(ex, "Exception while dispatching Framework::Update event.");
}
return this.updateHook.Original(framework);
}
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Runtime.InteropServices;
namespace Dalamud.Game.Internal {
public sealed class FrameworkAddressResolver : BaseAddressResolver {
public IntPtr BaseAddress { get; private set; }
public IntPtr GuiManager { get; private set; }
public IntPtr ScriptManager { get; private set; }
protected override void Setup64Bit(SigScanner sig) {
SetupFramework(sig);
// Xiv__Framework__GetGuiManager+8 000 mov rax, [rcx+2C00h]
// Xiv__Framework__GetGuiManager+F 000 retn
GuiManager = Marshal.ReadIntPtr(BaseAddress, 0x2C08);
// Called from Framework::Init
ScriptManager = BaseAddress + 0x2C68; // note that no deref here
}
private void SetupFramework(SigScanner scanner) {
// Dissasembly of part of the .dtor
// 00007FF701AD665A | 48 C7 05 ?? ?? ?? ?? 00 00 00 00 | MOV QWORD PTR DS:[g_mainFramework],0
// 00007FF701AD6665 | E8 ?? ?? ?? ?? | CALL ffxiv_dx11.7FF701E27130
// 00007FF701AD666A | 48 8D ?? ?? ?? 00 00 | LEA RCX,QWORD PTR DS:[RBX + 2C38]
// 00007FF701AD6671 | E8 ?? ?? ?? ?? | CALL ffxiv_dx11.7FF701E2A7D0
// 00007FF701AD6676 | 48 8D ?? ?? ?? ?? ?? | LEA RAX,QWORD PTR DS:[7FF702C31F80
var fwDtor = scanner.ScanText("48C705????????00000000 E8???????? 488D??????0000 E8???????? 488D");
var fwOffset = Marshal.ReadInt32(fwDtor + 3);
var pFramework = scanner.ResolveRelativeAddress(fwDtor + 11, fwOffset);
// Framework does not change once initialized in startup so don't bother to deref again and again.
BaseAddress = Marshal.ReadIntPtr(pFramework);
}
}
}

View file

@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Dalamud.Game.Chat;
using Dalamud.Game.Internal.Libc;
using Dalamud.Hooking;
using Serilog;
namespace Dalamud.Game.Internal.Gui {
public sealed class ChatGui : IDisposable {
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate void PrintMessageDelegate(IntPtr manager, XivChatType chatType, IntPtr senderName,
IntPtr message,
uint senderId, byte isLocal);
public delegate void OnMessageDelegate(XivChatType type, uint senderId, string sender, ref string message,
ref bool isHandled);
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate void PopulateItemLinkDelegate(IntPtr linkObjectPtr, IntPtr itemInfoPtr);
private readonly Queue<XivChatEntry> chatQueue = new Queue<XivChatEntry>();
private readonly Hook<PrintMessageDelegate> printMessageHook;
public event OnMessageDelegate OnChatMessage;
private readonly Hook<PopulateItemLinkDelegate> populateItemLinkHook;
public int LastLinkedItemId { get; private set; }
public byte LastLinkedItemFlags { get; private set; }
private ChatGuiAddressResolver Address { get; }
private IntPtr baseAddress = IntPtr.Zero;
private readonly Dalamud dalamud;
public ChatGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud) {
this.dalamud = dalamud;
Address = new ChatGuiAddressResolver(baseAddress);
Address.Setup(scanner);
Log.Verbose("Chat manager address {ChatManager}", Address.BaseAddress);
this.printMessageHook =
new Hook<PrintMessageDelegate>(Address.PrintMessage, new PrintMessageDelegate(HandlePrintMessageDetour),
this);
this.populateItemLinkHook =
new Hook<PopulateItemLinkDelegate>(Address.PopulateItemLinkObject,
new PopulateItemLinkDelegate(HandlePopulateItemLinkDetour),
this);
}
public void Enable() {
this.printMessageHook.Enable();
this.populateItemLinkHook.Enable();
}
public void Dispose() {
this.printMessageHook.Dispose();
this.populateItemLinkHook.Dispose();
}
private void HandlePopulateItemLinkDetour(IntPtr linkObjectPtr, IntPtr itemInfoPtr) {
try {
this.populateItemLinkHook.Original(linkObjectPtr, itemInfoPtr);
LastLinkedItemId = Marshal.ReadInt32(itemInfoPtr, 8);
LastLinkedItemFlags = Marshal.ReadByte(itemInfoPtr, 0x14);
Log.Debug($"HandlePopulateItemLinkDetour {linkObjectPtr} {itemInfoPtr} - linked:{LastLinkedItemId}");
} catch (Exception ex) {
Log.Error(ex, "Exception onPopulateItemLink hook.");
this.populateItemLinkHook.Original(linkObjectPtr, itemInfoPtr);
}
}
private void HandlePrintMessageDetour(IntPtr manager, XivChatType chattype, IntPtr pSenderName, IntPtr pMessage,
uint senderid, byte isLocal) {
try {
var senderName = StdString.ReadFromPointer(pSenderName);
var message = StdString.ReadFromPointer(pMessage);
//Log.Debug($"HandlePrintMessageDetour {manager} - [{chattype}] [{BitConverter.ToString(Encoding.UTF8.GetBytes(message))}] {message} from {senderName}");
var originalMessage = string.Copy(message);
// Call events
var isHandled = false;
OnChatMessage?.Invoke(chattype, senderid, senderName, ref message, ref isHandled);
var messagePtr = pMessage;
OwnedStdString allocatedString = null;
if (originalMessage != message) {
allocatedString = this.dalamud.Framework.Libc.NewString(message);
Log.Debug(
$"HandlePrintMessageDetour String modified: {originalMessage}({messagePtr}) -> {message}({allocatedString.Address})");
messagePtr = allocatedString.Address;
}
// Print the original chat if it's handled.
if (!isHandled)
this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, isLocal);
if (this.baseAddress == IntPtr.Zero)
this.baseAddress = manager;
allocatedString?.Dispose();
} catch (Exception ex) {
Log.Error(ex, "Exception on OnChatMessage hook.");
this.printMessageHook.Original(manager, chattype, pSenderName, pMessage, senderid, isLocal);
}
}
/// <summary>
/// Queue a chat message. While method is named as PrintChat, it only add a entry to the queue,
/// later to be processed when UpdateQueue() is called.
/// </summary>
/// <param name="chat">A message to send.</param>
public void PrintChat(XivChatEntry chat) {
this.chatQueue.Enqueue(chat);
}
public void Print(string message) {
PrintChat(new XivChatEntry {
Message = message
});
}
public void PrintError(string message) {
PrintChat(new XivChatEntry {
Message = message,
Type = XivChatType.Urgent
});
}
/// <summary>
/// Process a chat queue.
/// </summary>
public void UpdateQueue(Framework framework) {
while (this.chatQueue.Count > 0) {
var chat = this.chatQueue.Dequeue();
var sender = chat.Name ?? "";
var message = chat.Message ?? "";
if (this.baseAddress != IntPtr.Zero)
using (var senderVec = framework.Libc.NewString(sender))
using (var messageVec = framework.Libc.NewString(message)) {
this.printMessageHook.Original(this.baseAddress, chat.Type, senderVec.Address,
messageVec.Address, chat.SenderId, 0);
}
}
}
}
}

View file

@ -0,0 +1,88 @@
using System;
namespace Dalamud.Game.Internal.Gui {
public sealed class ChatGuiAddressResolver : BaseAddressResolver {
public IntPtr BaseAddress { get; }
public IntPtr PrintMessage { get; private set; }
public IntPtr PopulateItemLinkObject { get; private set; }
public ChatGuiAddressResolver(IntPtr baseAddres) {
BaseAddress = baseAddres;
}
/*
--- for reference: 4.57 ---
.text:00000001405CD210 ; __int64 __fastcall Xiv::Gui::ChatGui::PrintMessage(__int64 handler, unsigned __int16 chatType, __int64 senderName, __int64 message, int senderActorId, char isLocal)
.text:00000001405CD210 Xiv__Gui__ChatGui__PrintMessage proc near
.text:00000001405CD210 ; CODE XREF: sub_1401419F0+201p
.text:00000001405CD210 ; sub_140141D10+220p ...
.text:00000001405CD210
.text:00000001405CD210 var_220 = qword ptr -220h
.text:00000001405CD210 var_218 = byte ptr -218h
.text:00000001405CD210 var_210 = word ptr -210h
.text:00000001405CD210 var_208 = byte ptr -208h
.text:00000001405CD210 var_200 = word ptr -200h
.text:00000001405CD210 var_1FC = dword ptr -1FCh
.text:00000001405CD210 var_1F8 = qword ptr -1F8h
.text:00000001405CD210 var_1F0 = qword ptr -1F0h
.text:00000001405CD210 var_1E8 = qword ptr -1E8h
.text:00000001405CD210 var_1E0 = dword ptr -1E0h
.text:00000001405CD210 var_1DC = word ptr -1DCh
.text:00000001405CD210 var_1DA = word ptr -1DAh
.text:00000001405CD210 var_1D8 = qword ptr -1D8h
.text:00000001405CD210 var_1D0 = byte ptr -1D0h
.text:00000001405CD210 var_1C8 = qword ptr -1C8h
.text:00000001405CD210 var_1B0 = dword ptr -1B0h
.text:00000001405CD210 var_1AC = dword ptr -1ACh
.text:00000001405CD210 var_1A8 = dword ptr -1A8h
.text:00000001405CD210 var_1A4 = dword ptr -1A4h
.text:00000001405CD210 var_1A0 = dword ptr -1A0h
.text:00000001405CD210 var_160 = dword ptr -160h
.text:00000001405CD210 var_15C = dword ptr -15Ch
.text:00000001405CD210 var_140 = dword ptr -140h
.text:00000001405CD210 var_138 = dword ptr -138h
.text:00000001405CD210 var_130 = byte ptr -130h
.text:00000001405CD210 var_C0 = byte ptr -0C0h
.text:00000001405CD210 var_50 = qword ptr -50h
.text:00000001405CD210 var_38 = qword ptr -38h
.text:00000001405CD210 var_30 = qword ptr -30h
.text:00000001405CD210 var_28 = qword ptr -28h
.text:00000001405CD210 var_20 = qword ptr -20h
.text:00000001405CD210 senderActorId = dword ptr 30h
.text:00000001405CD210 isLocal = byte ptr 38h
.text:00000001405CD210
.text:00000001405CD210 ; __unwind { // __GSHandlerCheck
.text:00000001405CD210 push rbp
.text:00000001405CD212 push rdi
.text:00000001405CD213 push r14
.text:00000001405CD215 push r15
.text:00000001405CD217 lea rbp, [rsp-128h]
.text:00000001405CD21F sub rsp, 228h
.text:00000001405CD226 mov rax, cs:__security_cookie
.text:00000001405CD22D xor rax, rsp
.text:00000001405CD230 mov [rbp+140h+var_50], rax
.text:00000001405CD237 xor r10b, r10b
.text:00000001405CD23A mov [rsp+240h+var_1F8], rcx
.text:00000001405CD23F xor eax, eax
.text:00000001405CD241 mov r11, r9
.text:00000001405CD244 mov r14, r8
.text:00000001405CD247 mov r9d, eax
.text:00000001405CD24A movzx r15d, dx
.text:00000001405CD24E lea r8, [rcx+0C10h]
.text:00000001405CD255 mov rdi, rcx
*/
protected override void Setup64Bit(SigScanner sig) {
PrintMessage = sig.ScanText("4055 57 41 ?? 41 ?? 488DAC24D8FEFFFF 4881EC28020000 488B05???????? 4833C4 488985F0000000 4532D2 48894C2448");
//PrintMessage = sig.ScanText("4055 57 41 ?? 41 ?? 488DAC24E8FEFFFF 4881EC18020000 488B05???????? 4833C4 488985E0000000 4532D2 48894C2438"); old
//PrintMessage = sig.ScanText("40 55 57 41 56 41 57 48 8D AC 24 D8 FE FF FF 48 81 EC 28 02 00 00 48 8B 05 63 47 4A 01 48 33 C4 48 89 85 F0 00 00 00 45 32 D2 48 89 4C 24 48 33");
//PopulateItemLinkObject = sig.ScanText("48 89 5C 24 08 57 48 83 EC 20 80 7A 06 00 48 8B DA 48 8B F9 74 14 48 8B CA E8 32 03 00 00 48 8B C8 E8 FA F2 B0 FF 8B C8 EB 1D 0F B6 42 14 8B 4A");
PopulateItemLinkObject = sig.ScanText("48 89 5C 24 08 57 48 83 EC 20 80 7A 06 00 48 8B DA 48 8B F9 74 14 48 8B CA E8 32 03 00 00 48 8B C8 E8 ?? ?? B0 FF 8B C8 EB 1D 0F B6 42 14 8B 4A");
}
}
}

View file

@ -0,0 +1,27 @@
using System;
using Serilog;
namespace Dalamud.Game.Internal.Gui {
public sealed class GameGui : IDisposable {
private GameGuiAddressResolver Address { get; }
public ChatGui Chat { get; private set; }
public GameGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud) {
Address = new GameGuiAddressResolver(baseAddress);
Address.Setup(scanner);
Log.Verbose("GameGuiManager address {Address}", Address.BaseAddress);
Chat = new ChatGui(Address.ChatManager, scanner, dalamud);
}
public void Enable() {
Chat.Enable();
}
public void Dispose() {
Chat.Dispose();
}
}
}

View file

@ -0,0 +1,27 @@
using System;
using System.Runtime.InteropServices;
namespace Dalamud.Game.Internal.Gui {
public sealed class GameGuiAddressResolver : BaseAddressResolver {
public IntPtr BaseAddress { get; private set; }
public IntPtr ChatManager { get; private set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr GetChatManagerDelegate(IntPtr guiManager);
protected override void SetupInternal(SigScanner scanner) {
// Xiv__UiManager__GetChatManager 000 lea rax, [rcx+13E0h]
// Xiv__UiManager__GetChatManager+7 000 retn
ChatManager = BaseAddress + 0x13E0;
}
protected override void Setup64Bit(SigScanner sig) {
// Do nothing, still required.
}
}
}

View file

@ -0,0 +1,48 @@
using System;
using System.Runtime.InteropServices;
using Serilog;
namespace Dalamud.Game.Internal.Libc {
public sealed class LibcFunction {
// TODO: prolly callconv is not okay in x86
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr StdStringFromCStringDelegate(IntPtr pStdString, [MarshalAs(UnmanagedType.LPUTF8Str)]string content, IntPtr size);
// TODO: prolly callconv is not okay in x86
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr StdStringDeallocateDelegate(IntPtr address);
private LibcFunctionAddressResolver Address { get; }
private readonly StdStringFromCStringDelegate stdStringCtorCString;
private readonly StdStringDeallocateDelegate stdStringDeallocate;
public LibcFunction(SigScanner scanner) {
Address = new LibcFunctionAddressResolver();
Address.Setup(scanner);
this.stdStringCtorCString = Marshal.GetDelegateForFunctionPointer<StdStringFromCStringDelegate>(Address.StdStringFromCstring);
this.stdStringDeallocate = Marshal.GetDelegateForFunctionPointer<StdStringDeallocateDelegate>(Address.StdStringDeallocate);
}
public OwnedStdString NewString(string content) {
Log.Verbose("Allocating");
// While 0x70 bytes in the memory should be enough in DX11 version,
// I don't trust my analysis so we're just going to allocate almost two times more than that.
var pString = Marshal.AllocHGlobal(256);
// Initialize a string
var npos = new IntPtr(0xFFFFFFFF); // assumed to be -1 (0xFFFFFFFF in x86, 0xFFFFFFFF_FFFFFFFF in amd64)
var pReallocString = this.stdStringCtorCString(pString, content, npos);
Log.Verbose("Prev: {Prev} Now: {Now}", pString, pReallocString);
return new OwnedStdString(pReallocString, DeallocateStdString);
}
private void DeallocateStdString(IntPtr address) {
this.stdStringDeallocate(address);
}
}
}

View file

@ -0,0 +1,16 @@
using System;
using System.Security.Policy;
namespace Dalamud.Game.Internal.Libc {
public sealed class LibcFunctionAddressResolver : BaseAddressResolver {
private delegate IntPtr StringFromCString();
public IntPtr StdStringFromCstring { get; private set; }
public IntPtr StdStringDeallocate { get; private set; }
protected override void Setup64Bit(SigScanner sig) {
StdStringFromCstring = sig.ScanText("48895C2408 4889742410 57 4883EC20 488D4122 66C741200101 488901 498BD8");
StdStringDeallocate = sig.ScanText("80792100 7512 488B5108 41B833000000 488B09 E9??????00 C3");
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using System.Runtime.InteropServices;
using Serilog;
namespace Dalamud.Game.Internal.Libc {
public sealed class OwnedStdString : IDisposable {
internal delegate void DeallocatorDelegate(IntPtr address);
// ala. the drop flag
private bool isDisposed;
private readonly DeallocatorDelegate dealloc;
public IntPtr Address { get; private set; }
/// <summary>
/// Construct a wrapper around std::string
/// </summary>
/// <remarks>
/// Violating any of these might cause an undefined hehaviour.
/// 1. This function takes the ownership of the address.
/// 2. A memory pointed by address argument is assumed to be allocated by Marshal.AllocHGlobal thus will try to call Marshal.FreeHGlobal on the address.
/// 3. std::string object pointed by address must be initialized before calling this function.
/// </remarks>
/// <param name="address"></param>
/// <param name="dealloc">A deallocator function.</param>
/// <returns></returns>
internal OwnedStdString(IntPtr address, DeallocatorDelegate dealloc) {
Address = address;
this.dealloc = dealloc;
}
~OwnedStdString() {
ReleaseUnmanagedResources();
}
private void ReleaseUnmanagedResources() {
if (Address == IntPtr.Zero) {
// Something got seriously fucked.
throw new AccessViolationException();
}
Log.Verbose("Deallocting {Addr}", Address);
// Deallocate inner string first
this.dealloc(Address);
// Free the heap
Marshal.FreeHGlobal(Address);
// Better safe (running on a nullptr) than sorry. (running on a dangling pointer)
Address = IntPtr.Zero;
}
public void Dispose() {
// No double free plz, kthx.
if (this.isDisposed) {
return;
}
this.isDisposed = true;
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
public string Read() {
return StdString.ReadFromPointer(Address);
}
}
}

View file

@ -0,0 +1,33 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Dalamud.Game.Internal.Libc {
/// <summary>
/// Interation with std::string
/// </summary>
public static class StdString {
public static string ReadFromPointer(IntPtr cstring) {
unsafe {
if (cstring == IntPtr.Zero) {
throw new ArgumentNullException(nameof(cstring));
}
var innerAddress = Marshal.ReadIntPtr(cstring);
if (innerAddress == IntPtr.Zero) {
throw new NullReferenceException("Inner reference to the cstring is null.");
}
var pInner = (sbyte*) innerAddress.ToPointer();
var count = 0;
// Count the number of chars. String is assumed to be zero-terminated.
while (*(pInner + count) != 0) {
count += 1;
}
return new string(pInner, 0, count, Encoding.UTF8);
}
}
}
}

View file

@ -0,0 +1,64 @@
using System;
using System.Runtime.InteropServices;
using Dalamud.Hooking;
using Serilog;
namespace Dalamud.Game.Internal.Network {
public sealed class GameNetwork : IDisposable {
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate void ProcessZonePacketDelegate(IntPtr a, IntPtr b, IntPtr dataPtr);
private readonly Hook<ProcessZonePacketDelegate> processZonePacketHook;
private GameNetworkAddressResolver Address { get; }
public delegate void OnZonePacketDelegate(IntPtr dataPtr);
public OnZonePacketDelegate OnZonePacket;
private readonly Dalamud dalamud;
public GameNetwork(Dalamud dalamud, SigScanner scanner) {
this.dalamud = dalamud;
Address = new GameNetworkAddressResolver();
Address.Setup(scanner);
Log.Verbose("ProcessZonePacket address {ProcessZonePacket}", Address.ProcessZonePacket);
this.processZonePacketHook =
new Hook<ProcessZonePacketDelegate>(Address.ProcessZonePacket,
new ProcessZonePacketDelegate(ProcessZonePacketDetour),
this);
}
public void Enable() {
this.processZonePacketHook.Enable();
}
public void Dispose() {
this.processZonePacketHook.Dispose();
}
private void ProcessZonePacketDetour(IntPtr a, IntPtr b, IntPtr dataPtr) {
// Call events
this.OnZonePacket?.Invoke(dataPtr);
try {
this.processZonePacketHook.Original(a, b, dataPtr);
} catch (Exception ex) {
string header;
try {
var data = new byte[32];
Marshal.Copy(dataPtr, data, 0, 32);
header = BitConverter.ToString(data);
} catch (Exception) {
header = "failed";
}
Log.Error(ex, "Exception on ProcessZonePacket hook. Header: " + header);
this.processZonePacketHook.Original(a, b, dataPtr);
}
}
}
}

View file

@ -0,0 +1,11 @@
using System;
namespace Dalamud.Game.Internal.Network {
public sealed class GameNetworkAddressResolver : BaseAddressResolver {
public IntPtr ProcessZonePacket { get; private set; }
protected override void Setup64Bit(SigScanner sig) {
ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 7A FF 0F B7 57 02 8D 42 89 3D 5F 02 00 00 0F 87 60 01 00 00 4C 8D 05");
}
}
}

View file

@ -0,0 +1,16 @@
using System.Collections.Generic;
using Dalamud.Game.Network.Structures;
namespace Dalamud.Game.Network {
internal class MarketBoardItemRequest {
public uint CatalogId { get; set; }
public byte AmountToArrive { get; set; }
public List<MarketBoardCurrentOfferings.MarketBoardItemListing> Listings { get; set; }
public List<MarketBoardHistory.MarketBoardHistoryListing> History { get; set; }
public int ListingsRequestId { get; set; } = -1;
public bool IsDone => Listings.Count == AmountToArrive && History.Count != 0;
}
}

View file

@ -0,0 +1,5 @@
namespace Dalamud.Game.Network.MarketBoardUploaders {
internal interface IMarketBoardUploader {
void Upload(MarketBoardItemRequest itemRequest);
}
}

View file

@ -0,0 +1,29 @@
using Newtonsoft.Json;
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
internal class UniversalisHistoryEntry {
[JsonProperty("hq")]
public bool Hq { get; set; }
[JsonProperty("pricePerUnit")]
public uint PricePerUnit { get; set; }
[JsonProperty("quantity")]
public uint Quantity { get; set; }
[JsonProperty("buyerName")]
public string BuyerName { get; set; }
[JsonProperty("onMannequin")]
public bool OnMannequin { get; set; }
[JsonProperty("sellerID")]
public ulong SellerId { get; set; }
[JsonProperty("buyerID")]
public ulong BuyerId { get; set; }
[JsonProperty("timestamp")]
public long Timestamp { get; set; }
}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
internal class UniversalisHistoryUploadRequest {
[JsonProperty("worldID")]
public int WorldId { get; set; }
[JsonProperty("itemID")]
public uint ItemId { get; set; }
[JsonProperty("entries")]
public List<UniversalisHistoryEntry> Entries { get; set; }
[JsonProperty("uploaderID")]
public ulong UploaderId { get; set; }
}
}

View file

@ -0,0 +1,48 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
internal class UniversalisItemListingsEntry {
[JsonProperty("listingID")]
public ulong ListingId { get; set; }
[JsonProperty("hq")]
public bool Hq { get; set; }
[JsonProperty("pricePerUnit")]
public uint PricePerUnit { get; set; }
[JsonProperty("quantity")]
public uint Quantity { get; set; }
[JsonProperty("retainerName")]
public string RetainerName { get; set; }
[JsonProperty("retainerID")]
public ulong RetainerId { get; set; }
[JsonProperty("creatorName")]
public string CreatorName { get; set; }
[JsonProperty("onMannequin")]
public bool OnMannequin { get; set; }
[JsonProperty("sellerID")]
public ulong SellerId { get; set; }
[JsonProperty("creatorID")]
public ulong CreatorId { get; set; }
[JsonProperty("stainID")]
public int StainId { get; set; }
[JsonProperty("retainerCity")]
public int RetainerCity { get; set; }
[JsonProperty("lastReviewTime")]
public long LastReviewTime { get; set; }
[JsonProperty("materia")]
public List<UniversalisItemMateria> Materia { get; set; }
}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
internal class UniversalisItemListingsUploadRequest {
[JsonProperty("worldID")]
public int WorldId { get; set; }
[JsonProperty("itemID")]
public uint ItemId { get; set; }
[JsonProperty("listings")]
public List<UniversalisItemListingsEntry> Listings { get; set; }
[JsonProperty("uploaderID")]
public ulong UploaderId { get; set; }
}
}

View file

@ -0,0 +1,11 @@
using Newtonsoft.Json;
namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
internal class UniversalisItemMateria {
[JsonProperty("slotID")]
public int SlotId { get; set; }
[JsonProperty("materiaID")]
public int MateriaId { get; set; }
}
}

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Net;
using Dalamud.Game.Network.MarketBoardUploaders;
using Dalamud.Game.Network.MarketBoardUploaders.Universalis;
using Newtonsoft.Json;
using Serilog;
namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders {
internal class UniversalisMarketBoardUploader : IMarketBoardUploader {
private const string ApiBase = "https://universalis.app";
//private const string ApiBase = "https://127.0.0.1:443";
private const string ApiKey = "GGD6RdSfGyRiHM5WDnAo0Nj9Nv7aC5NDhMj3BebT";
private readonly Dalamud dalamud;
public UniversalisMarketBoardUploader(Dalamud dalamud) {
this.dalamud = dalamud;
}
public void Upload(MarketBoardItemRequest request) {
using (var client = new WebClient()) {
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
Log.Verbose("Starting Universalis upload.");
var uploader = this.dalamud.ClientState.LocalContentId;
var listingsRequestObject = new UniversalisItemListingsUploadRequest();
listingsRequestObject.WorldId = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Id;
listingsRequestObject.UploaderId = uploader;
listingsRequestObject.ItemId = request.CatalogId;
listingsRequestObject.Listings = new List<UniversalisItemListingsEntry>();
foreach (var marketBoardItemListing in request.Listings) {
var universalisListing = new UniversalisItemListingsEntry {
Hq = marketBoardItemListing.IsHq,
SellerId = marketBoardItemListing.RetainerOwnerId,
RetainerName = marketBoardItemListing.RetainerName,
RetainerId = marketBoardItemListing.RetainerId,
CreatorId = marketBoardItemListing.ArtisanId,
CreatorName = marketBoardItemListing.PlayerName,
OnMannequin = marketBoardItemListing.OnMannequin,
LastReviewTime = ((DateTimeOffset) marketBoardItemListing.LastReviewTime).ToUnixTimeSeconds(),
PricePerUnit = marketBoardItemListing.PricePerUnit,
Quantity = marketBoardItemListing.ItemQuantity,
RetainerCity = marketBoardItemListing.RetainerCityId
};
universalisListing.Materia = new List<UniversalisItemMateria>();
foreach (var itemMateria in marketBoardItemListing.Materia)
universalisListing.Materia.Add(new UniversalisItemMateria {
MateriaId = itemMateria.MateriaId,
SlotId = itemMateria.Index
});
listingsRequestObject.Listings.Add(universalisListing);
}
var upload = JsonConvert.SerializeObject(listingsRequestObject);
client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", upload);
Log.Verbose(upload);
var historyRequestObject = new UniversalisHistoryUploadRequest();
historyRequestObject.WorldId = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Id;
historyRequestObject.UploaderId = uploader;
historyRequestObject.ItemId = request.CatalogId;
historyRequestObject.Entries = new List<UniversalisHistoryEntry>();
foreach (var marketBoardHistoryListing in request.History)
historyRequestObject.Entries.Add(new UniversalisHistoryEntry {
BuyerName = marketBoardHistoryListing.BuyerName,
Hq = marketBoardHistoryListing.IsHq,
OnMannequin = marketBoardHistoryListing.OnMannequin,
PricePerUnit = marketBoardHistoryListing.SalePrice,
Quantity = marketBoardHistoryListing.Quantity,
Timestamp = ((DateTimeOffset) marketBoardHistoryListing.PurchaseTime).ToUnixTimeSeconds()
});
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
var historyUpload = JsonConvert.SerializeObject(historyRequestObject);
client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload);
Log.Verbose(historyUpload);
Log.Verbose("Universalis data upload for item#{0} completed.", request.CatalogId);
}
}
}
}

View file

@ -0,0 +1,192 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Dalamud.Game.Network.MarketBoardUploaders;
using Dalamud.Game.Network.Structures;
using Dalamud.Game.Network.Universalis.MarketBoardUploaders;
using Dalamud.Settings;
using Serilog;
namespace Dalamud.Game.Network {
public class NetworkHandlers {
private readonly Dalamud dalamud;
private readonly List<MarketBoardItemRequest> marketBoardRequests = new List<MarketBoardItemRequest>();
private readonly bool optOutMbUploads;
private readonly IMarketBoardUploader uploader;
public NetworkHandlers(Dalamud dalamud, bool optOutMbUploads) {
this.dalamud = dalamud;
this.optOutMbUploads = optOutMbUploads;
this.uploader = new UniversalisMarketBoardUploader(dalamud);
dalamud.Framework.Network.OnZonePacket += OnZonePacket;
}
private void OnZonePacket(IntPtr dataPtr) {
var opCode = (ZoneOpCode) Marshal.ReadInt16(dataPtr, 2);
if (opCode == ZoneOpCode.RetainerSaleItemId) {
var itemId = Marshal.ReadInt32(dataPtr + 16);
var amount = Marshal.ReadByte(dataPtr + 32);
var isHq = false;
if (itemId > 1000000) {
itemId -= 1000000;
isHq = true;
}
Task.Run(() => this.dalamud.BotManager.ProcessRetainerSale(itemId, amount, isHq));
return;
}
if (opCode == ZoneOpCode.FateSpawn) {
if (PersistentSettings.Instance.Fates == null)
return;
var data = new byte[64];
Marshal.Copy(dataPtr, data, 0, 64);
var fateId = data[16];
if (PersistentSettings.Instance.Fates.Any(x => x.Id == fateId) &&
this.dalamud.BotManager.IsConnected)
Task.Run(() => this.dalamud.BotManager.ProcessFate(fateId));
return;
}
if (opCode == ZoneOpCode.CfNotify) {
var data = new byte[64];
Marshal.Copy(dataPtr, data, 0, 64);
var notifyType = data[16];
var contentFinderConditionId = BitConverter.ToInt16(data, 38);
Task.Run(async () => {
if (notifyType != 4)
return;
var contentFinderCondition =
await XivApi.GetContentFinderCondition(contentFinderConditionId);
this.dalamud.Framework.Gui.Chat.Print("Duty Finder pop: " + contentFinderCondition["Name"]);
if (this.dalamud.BotManager.IsConnected)
await this.dalamud.BotManager.ProcessCfPop(contentFinderCondition);
});
return;
}
if (!this.optOutMbUploads) {
if (opCode == ZoneOpCode.MarketBoardItemRequestStart) {
var catalogId = (uint) Marshal.ReadInt32(dataPtr + 0x10);
var amount = Marshal.ReadByte(dataPtr + 0x1B);
this.marketBoardRequests.Add(new MarketBoardItemRequest {
CatalogId = catalogId,
AmountToArrive = amount,
Listings = new List<MarketBoardCurrentOfferings.MarketBoardItemListing>(),
History = new List<MarketBoardHistory.MarketBoardHistoryListing>()
});
Log.Verbose($"NEW MB REQUEST START: item#{catalogId} amount#{amount}");
return;
}
if (opCode == ZoneOpCode.MarketBoardOfferings) {
var listing = MarketBoardCurrentOfferings.Read(dataPtr + 0x10);
var request =
this.marketBoardRequests.LastOrDefault(
r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone);
if (request == null) {
Log.Error(
$"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}");
return;
}
if (request.Listings.Count + listing.ItemListings.Count > request.AmountToArrive) {
Log.Error(
$"Too many Market Board listings received for request: {request.Listings.Count + listing.ItemListings.Count} > {request.AmountToArrive} item#{listing.ItemListings[0].CatalogId}");
return;
}
if (request.ListingsRequestId != -1 && request.ListingsRequestId != listing.RequestId) {
Log.Error(
$"Non-matching RequestIds for Market Board data request: {request.ListingsRequestId}, {listing.RequestId}");
return;
}
if (request.ListingsRequestId == -1 && request.Listings.Count > 0) {
Log.Error(
$"Market Board data request sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
return;
}
if (request.ListingsRequestId == -1) {
request.ListingsRequestId = listing.RequestId;
Log.Verbose($"First Market Board packet in sequence: {listing.RequestId}");
}
request.Listings.AddRange(listing.ItemListings);
Log.Verbose("Added {0} ItemListings to request#{1}, now {2}/{3}, item#{4}",
listing.ItemListings.Count, request.ListingsRequestId, request.Listings.Count,
request.AmountToArrive, request.CatalogId);
if (request.IsDone) {
Log.Verbose("Market Board request finished, starting upload: request#{0} item#{1} amount#{2}",
request.ListingsRequestId, request.CatalogId, request.AmountToArrive);
try {
Task.Run(() => this.uploader.Upload(request));
} catch (Exception ex) {
Log.Error(ex, "Market Board data upload failed.");
}
}
return;
}
if (opCode == ZoneOpCode.MarketBoardHistory) {
var listing = MarketBoardHistory.Read(dataPtr + 0x10);
var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId);
if (request == null) {
Log.Error(
$"Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
return;
}
if (request.ListingsRequestId != -1) {
Log.Error(
$"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
return;
}
request.History.AddRange(listing.HistoryListings);
Log.Verbose("Added history for item#{0}", listing.CatalogId);
}
}
}
private enum ZoneOpCode {
CfNotify = 0x78,
RetainerSaleItemId = 0x13F, // TODO these are probably not accurate
RetainerSaleFinish = 0x138,
FateSpawn = 0x226,
MarketBoardItemRequestStart = 0x13B,
MarketBoardOfferings = 0x13C,
MarketBoardHistory = 0x140
}
}
}

View file

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Dalamud.Game.Network.Structures {
public class MarketBoardCurrentOfferings {
public List<MarketBoardItemListing> ItemListings;
public int ListingIndexEnd;
public int ListingIndexStart;
public int RequestId;
public static unsafe MarketBoardCurrentOfferings Read(IntPtr dataPtr) {
var output = new MarketBoardCurrentOfferings();
using (var stream = new UnmanagedMemoryStream((byte*) dataPtr.ToPointer(), 1544)) {
using (var reader = new BinaryReader(stream)) {
output.ItemListings = new List<MarketBoardItemListing>();
for (var i = 0; i < 10; i++) {
var listingEntry = new MarketBoardItemListing();
listingEntry.ListingId = reader.ReadUInt64();
listingEntry.RetainerId = reader.ReadUInt64();
listingEntry.RetainerOwnerId = reader.ReadUInt64();
listingEntry.ArtisanId = reader.ReadUInt64();
listingEntry.PricePerUnit = reader.ReadUInt32();
listingEntry.TotalTax = reader.ReadUInt32();
listingEntry.ItemQuantity = reader.ReadUInt32();
listingEntry.CatalogId = reader.ReadUInt32();
listingEntry.LastReviewTime = DateTimeOffset.UtcNow.AddSeconds(-reader.ReadUInt16()).DateTime;
reader.ReadUInt16(); // container
reader.ReadUInt32(); // slot
reader.ReadUInt16(); // durability
reader.ReadUInt16(); // spiritbond
listingEntry.Materia = new List<MarketBoardItemListing.ItemMateria>();
for (var materiaIndex = 0; materiaIndex < 5; materiaIndex++) {
var materiaVal = reader.ReadUInt16();
var materiaEntry = new MarketBoardItemListing.ItemMateria();
materiaEntry.MateriaId = (materiaVal & 0xFF0) >> 4;
materiaEntry.Index = materiaVal & 0xF;
if (materiaEntry.MateriaId != 0)
listingEntry.Materia.Add(materiaEntry);
}
reader.ReadUInt16();
reader.ReadUInt32();
listingEntry.RetainerName = Encoding.UTF8.GetString(reader.ReadBytes(32)).TrimEnd('\u0000');
listingEntry.PlayerName = Encoding.UTF8.GetString(reader.ReadBytes(32)).TrimEnd('\u0000');
listingEntry.IsHq = reader.ReadBoolean();
listingEntry.MateriaCount = reader.ReadByte();
listingEntry.OnMannequin = reader.ReadBoolean();
listingEntry.RetainerCityId = reader.ReadByte();
listingEntry.StainId = reader.ReadUInt16();
reader.ReadUInt16();
reader.ReadUInt32();
if (listingEntry.CatalogId != 0)
output.ItemListings.Add(listingEntry);
}
output.ListingIndexEnd = reader.ReadByte();
output.ListingIndexStart = reader.ReadByte();
output.RequestId = reader.ReadUInt16();
}
}
return output;
}
public class MarketBoardItemListing {
public ulong ArtisanId;
public uint CatalogId;
public bool IsHq;
public uint ItemQuantity;
public DateTime LastReviewTime;
public ulong ListingId;
public List<ItemMateria> Materia;
public int MateriaCount;
public bool OnMannequin;
public string PlayerName;
public uint PricePerUnit;
public int RetainerCityId;
public ulong RetainerId;
public string RetainerName;
public ulong RetainerOwnerId;
public int StainId;
public uint TotalTax;
public class ItemMateria {
public int Index;
public int MateriaId;
}
}
}
}

View file

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Dalamud.Game.Network.Structures {
public class MarketBoardHistory {
public uint CatalogId;
public uint CatalogId2;
public List<MarketBoardHistoryListing> HistoryListings;
public static unsafe MarketBoardHistory Read(IntPtr dataPtr) {
var output = new MarketBoardHistory();
using (var stream = new UnmanagedMemoryStream((byte*) dataPtr.ToPointer(), 1544)) {
using (var reader = new BinaryReader(stream)) {
output.CatalogId = reader.ReadUInt32();
output.CatalogId2 = reader.ReadUInt32();
output.HistoryListings = new List<MarketBoardHistoryListing>();
for (var i = 0; i < 10; i++) {
var listingEntry = new MarketBoardHistoryListing();
listingEntry.SalePrice = reader.ReadUInt32();
listingEntry.PurchaseTime = DateTimeOffset.FromUnixTimeSeconds(reader.ReadUInt32()).UtcDateTime;
listingEntry.Quantity = reader.ReadUInt32();
listingEntry.IsHq = reader.ReadBoolean();
reader.ReadBoolean();
listingEntry.OnMannequin = reader.ReadBoolean();
listingEntry.BuyerName = Encoding.UTF8.GetString(reader.ReadBytes(33)).TrimEnd('\u0000');
listingEntry.CatalogId = reader.ReadUInt32();
if (listingEntry.CatalogId != 0)
output.HistoryListings.Add(listingEntry);
}
}
}
return output;
}
public class MarketBoardHistoryListing {
public string BuyerName;
public uint CatalogId;
public bool IsHq;
public bool OnMannequin;
public DateTime PurchaseTime;
public uint Quantity;
public uint SalePrice;
}
}
}

148
Dalamud/Game/SigScanner.cs Normal file
View file

@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Serilog;
namespace Dalamud.Game {
public sealed class SigScanner {
public SigScanner(ProcessModule module) {
Module = module;
Is32BitProcess = !Environment.Is64BitProcess;
// Limit the search space to .text section.
SetupSearchSpace(module);
Log.Verbose("Module base: {Address}", TextSectionBase);
Log.Verbose("Moudle size: {Size}", TextSectionSize);
}
public bool Is32BitProcess { get; }
public IntPtr TextSectionBase { get; private set; }
public int TextSectionSize { get; private set; }
public IntPtr DataSectionBase { get; private set; }
public int DataSectionSize { get; private set; }
public ProcessModule Module { get; }
private IntPtr TextSectionTop => TextSectionBase + TextSectionSize;
private void SetupSearchSpace(ProcessModule module) {
var baseAddress = module.BaseAddress;
// We don't want to read all of IMAGE_DOS_HEADER or IMAGE_NT_HEADER stuff so we cheat here.
var ntNewOffset = Marshal.ReadInt32(baseAddress, 0x3C);
var ntHeader = baseAddress + ntNewOffset;
// IMAGE_NT_HEADER
var fileHeader = ntHeader + 4;
var numSections = Marshal.ReadInt16(ntHeader, 6);
// IMAGE_OPTIONAL_HEADER
var optionalHeader = fileHeader + 20;
IntPtr sectionHeader;
if (Is32BitProcess) // IMAGE_OPTIONAL_HEADER32
sectionHeader = optionalHeader + 224;
else // IMAGE_OPTIONAL_HEADER64
sectionHeader = optionalHeader + 240;
// IMAGE_SECTION_HEADER
var sectionCursor = sectionHeader;
for (var i = 0; i < numSections; i++) {
var sectionName = Marshal.ReadInt64(sectionCursor);
// .text
switch (sectionName) {
case 0x747865742E: // .text
TextSectionBase = baseAddress + Marshal.ReadInt32(sectionCursor, 12);
TextSectionSize = Marshal.ReadInt32(sectionCursor, 8);
break;
case 0x617461642E: // .data
DataSectionBase = baseAddress + Marshal.ReadInt32(sectionCursor, 12);
DataSectionSize = Marshal.ReadInt32(sectionCursor, 8);
break;
}
sectionCursor += 40;
}
}
public IntPtr ScanText(string signature) {
return Scan(TextSectionBase, TextSectionSize, signature);
}
public IntPtr ScanData(string signature) {
return Scan(DataSectionBase, DataSectionSize, signature);
}
public IntPtr ScanModule(string signature) {
return Scan(Module.BaseAddress, Module.ModuleMemorySize, signature);
}
public IntPtr Scan(IntPtr baseAddress, int size, string signature) {
var needle = SigToNeedle(signature);
unsafe {
var pCursor = (byte*) baseAddress.ToPointer();
var pTop = (byte*) (baseAddress + size - needle.Length);
while (pCursor < pTop) {
if (IsMatch(pCursor, needle)) return (IntPtr) pCursor;
// Advance an offset
pCursor += 1;
}
}
throw new KeyNotFoundException($"Can't find a signature of {signature}");
}
public IntPtr ResolveRelativeAddress(IntPtr nextInstAddr, int relOffset) {
if (Is32BitProcess) throw new NotSupportedException("32 bit is not supported.");
return nextInstAddr + relOffset;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe bool IsMatch(byte* pCursor, byte?[] needle) {
for (var i = 0; i < needle.Length; i++) {
var expected = needle[i];
if (expected == null) continue;
var actual = *(pCursor + i);
if (expected != actual) return false;
}
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte?[] SigToNeedle(string signature) {
// Strip all whitespaces
signature = signature.Replace(" ", "");
if (signature.Length % 2 != 0)
throw new ArgumentException("Signature without whitespaces must be divisible by two.",
nameof(signature));
var needleLength = signature.Length / 2;
var needle = new byte?[needleLength];
for (var i = 0; i < needleLength; i++) {
var hexString = signature.Substring(i * 2, 2);
if (hexString == "??" || hexString == "**") {
needle[i] = null;
continue;
}
needle[i] = byte.Parse(hexString, NumberStyles.AllowHexSpecifier);
}
return needle;
}
}
}

112
Dalamud/Hooking/Hook.cs Normal file
View file

@ -0,0 +1,112 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using EasyHook;
namespace Dalamud.Hooking {
/// <summary>
/// Manages a hook which can be used to intercept a call to native function.
/// This class is basically a thin wrapper around the LocalHook type to provide helper functions.
/// </summary>
/// <typeparam name="T">Delegate type to represents a function prototype. This must be the same prototype as original function do.</typeparam>
public sealed class Hook<T> : IDisposable where T : class {
private bool isDisposed;
private readonly IntPtr address;
private readonly T original;
private readonly LocalHook hookInfo;
/// <summary>
/// A memory address of the target function.
/// </summary>
/// <exception cref="ObjectDisposedException">Hook is already disposed.</exception>
public IntPtr Address {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
CheckDisposed();
return this.address;
}
}
/// <summary>
/// A delegate function that can be used to call the actual function as if function is not hooked yet.
/// </summary>
/// <remarks></remarks>
/// <exception cref="ObjectDisposedException">Hook is already disposed.</exception>
public T Original {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
CheckDisposed();
return this.original;
}
}
/// <summary>
/// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. Hook is not activated until Enable() method is called.
/// </summary>
/// <param name="moduleName">A name of the module currently loaded in the memory. (e.g. ws2_32.dll)</param>
/// <param name="exportName">A name of the exported function name (e.g. send)</param>
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
/// <param name="callbackParam">A callback object which can be accessed within the detour.</param>
/// <returns></returns>
public static Hook<T> FromSymbol(string moduleName, string exportName, Delegate detour, object callbackParam = null) {
// Get a function address from the symbol name.
var address = LocalHook.GetProcAddress(moduleName, exportName);
return new Hook<T>(address, detour, callbackParam);
}
/// <summary>
/// Createss a hook. Hook is not activated until Enable() method is called.
/// </summary>
/// <param name="address">A memory address to install a hook.</param>
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
/// <param name="callbackParam">A callback object which can be accessed within the detour.</param>
public Hook(IntPtr address, Delegate detour, object callbackParam = null) {
this.hookInfo = LocalHook.Create(address, detour, callbackParam); // Installs a hook here
this.address = address;
this.original = Marshal.GetDelegateForFunctionPointer<T>(this.hookInfo.HookBypassAddress);
}
/// <summary>
/// Remove a hook from the current process.
/// </summary>
public void Dispose() {
if (this.isDisposed) {
return;
}
this.hookInfo.Dispose();
this.isDisposed = true;
}
/// <summary>
/// Starts intercepting a call to the function.
/// </summary>
public void Enable() {
CheckDisposed();
this.hookInfo.ThreadACL.SetExclusiveACL(null);
}
/// <summary>
/// Stops intercepting a call to the function.
/// </summary>
public void Disable() {
CheckDisposed();
this.hookInfo.ThreadACL.SetInclusiveACL(null);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CheckDisposed() {
if (this.isDisposed) {
throw new ObjectDisposedException("Hook is already disposed.");
}
}
}
}

View file

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Game.ClientState;
using Dalamud.Game.Command;
using Dalamud.Game.Internal;
using Dalamud.Game.Internal.Gui;
namespace Dalamud.Plugin
{
/// <summary>
/// This class acts as an interface to various objects needed to interact with Dalamud and the game.
/// </summary>
public class DalamudPluginInterface {
/// <summary>
/// The CommandManager object that allows you to add and remove custom chat commands.
/// </summary>
public readonly CommandManager CommandManager;
/// <summary>
/// The ClientState object that allows you to access current client memory information like actors, territories, etc.
/// </summary>
public readonly ClientState ClientState;
/// <summary>
/// The Framework object that allows you to interact with the client.
/// </summary>
public readonly Framework Framework;
/// <summary>
/// Set up the interface and populate all fields needed.
/// </summary>
/// <param name="dalamud"></param>
public DalamudPluginInterface(Dalamud dalamud) {
this.CommandManager = dalamud.CommandManager;
this.Framework = dalamud.Framework;
this.ClientState = dalamud.ClientState;
}
}
}

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dalamud.Plugin
{
/// <summary>
/// This interface represents a basic Dalamud plugin. All plugins have to implement this interface.
/// </summary>
public interface IDalamudPlugin : IDisposable
{
/// <summary>
/// The name of the plugin.
/// </summary>
string Name { get; }
/// <summary>
/// Initializes a Dalamud plugin.
/// </summary>
/// <param name="pluginInterface">The <see cref="DalamudPluginInterface"/> needed to access various Dalamud objects.</param>
void Initialize(DalamudPluginInterface pluginInterface);
}
}

View file

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Serilog;
namespace Dalamud.Plugin
{
public class PluginManager {
private readonly Dalamud dalamud;
private readonly string pluginDirectory;
private readonly string defaultPluginDirectory;
private readonly DalamudPluginInterface dalamudInterface;
private List<IDalamudPlugin> plugins;
public PluginManager(Dalamud dalamud, string pluginDirectory, string defaultPluginDirectory) {
this.dalamud = dalamud;
this.pluginDirectory = pluginDirectory;
this.defaultPluginDirectory = defaultPluginDirectory;
this.dalamudInterface = new DalamudPluginInterface(dalamud);
}
public void UnloadPlugins() {
if (this.plugins == null)
return;
for (var i = 0; i < this.plugins.Count; i++) {
this.plugins[i].Dispose();
this.plugins[i] = null;
}
}
public void LoadPlugins() {
LoadPluginsAt(this.defaultPluginDirectory);
LoadPluginsAt(this.pluginDirectory);
}
private void LoadPluginsAt(string folder) {
if (Directory.Exists(folder))
{
Log.Debug("Loading plugins at {0}", folder);
var pluginFileNames = Directory.GetFiles(folder, "*.dll");
var assemblies = new List<Assembly>(pluginFileNames.Length);
foreach (var dllFile in pluginFileNames)
{
Log.Debug("Loading assembly at {0}", dllFile);
var assemblyName = AssemblyName.GetAssemblyName(dllFile);
var pluginAssembly = Assembly.Load(assemblyName);
assemblies.Add(pluginAssembly);
}
var interfaceType = typeof(IDalamudPlugin);
var foundImplementations = new List<Type>();
foreach (var assembly in assemblies) {
if (assembly != null) {
Log.Debug("Loading types for {0}", assembly.FullName);
var types = assembly.GetTypes();
foreach (var type in types) {
if (type.IsInterface || type.IsAbstract) {
continue;
}
if (type.GetInterface(interfaceType.FullName) != null) {
foundImplementations.Add(type);
}
}
}
}
this.plugins = new List<IDalamudPlugin>(foundImplementations.Count);
foreach (var pluginType in foundImplementations)
{
var plugin = (IDalamudPlugin)Activator.CreateInstance(pluginType);
plugin.Initialize(this.dalamudInterface);
Log.Information("Loaded plugin: {0}", plugin.Name);
this.plugins.Add(plugin);
}
}
}
}
}

73
Dalamud/Properties/Resources.Designer.cs generated Normal file
View file

@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Dalamud.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Dalamud.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap eye {
get {
object obj = ResourceManager.GetObject("eye", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View file

@ -0,0 +1,969 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="eye" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
9gAAAABJRU5ErkJggg==
</value>
</data>
</root>

BIN
Dalamud/Resources/eye.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View file

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Dalamud.Settings
{
public class PersistentSettings {
private static PersistentSettings _instance = null;
private static readonly string ConfigPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "settings.json");
public static PersistentSettings Instance {
get {
if (_instance == null) {
if (!File.Exists(ConfigPath)) {
_instance = new PersistentSettings();
return _instance;
}
_instance = JsonConvert.DeserializeObject<PersistentSettings>(File.ReadAllText(ConfigPath));
}
return _instance;
}
}
public class FateInfo {
public string Name { get; set; }
public int Id { get; set; }
}
public List<FateInfo> Fates;
public List<string> BadWords;
public void Save() {
File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(this));
}
public static void Reset() {
_instance = new PersistentSettings();
Instance.Save();
}
}
}

86
Dalamud/XivApi.cs Normal file
View file

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CSharp.RuntimeBinder;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Dalamud
{
class XivApi
{
private const string URL = "http://xivapi.com/";
private static readonly Dictionary<string, JObject> cachedResponses = new Dictionary<string, JObject>();
public static async Task<JObject> GetWorld(int world)
{
var res = await Get("World/" + world);
return res;
}
public static async Task<JObject> GetClassJob(int id)
{
var res = await Get("ClassJob/" + id);
return res;
}
public static async Task<JObject> GetFate(int id)
{
var res = await Get("Fate/" + id);
return res;
}
public static async Task<JObject> GetCharacterSearch(string name, string world)
{
var res = await Get("character/search" + $"?name={name}&server={world}");
return res;
}
public static async Task<JObject> GetContentFinderCondition(int contentFinderCondition) {
return await Get("ContentFinderCondition/" + contentFinderCondition);
}
public static async Task<JObject> Search(string query, string indexes, int limit = 100) {
query = System.Net.WebUtility.UrlEncode(query);
return await Get("search" + $"?string={query}&indexes={indexes}&limit={limit}");
}
public static async Task<JObject> GetMarketInfoWorld(int itemId, string worldName) {
return await Get($"market/{worldName}/item/{itemId}", true);
}
public static async Task<JObject> GetMarketInfoDc(int itemId, string dcName) {
return await Get($"market/item/{itemId}?dc={dcName}", true);
}
public static async Task<JObject> GetItem(int itemId) {
return await Get($"Item/{itemId}", true);
}
public static async Task<dynamic> Get(string endpoint, bool noCache = false)
{
if (cachedResponses.ContainsKey(endpoint) && !noCache)
return cachedResponses[endpoint];
var client = new HttpClient();
var response = await client.GetAsync(URL + endpoint);
var result = await response.Content.ReadAsStringAsync();
var obj = JObject.Parse(result);
if (!noCache)
cachedResponses.Add(endpoint, obj);
return obj;
}
}
}

84
LICENSE Normal file
View file

@ -0,0 +1,84 @@
AFFERO GENERAL PUBLIC LICENSE
Version 1, March 2002Copyright © 2002 Affero Inc.510 Third Street - Suite 225, San Francisco, CA 94107, USA
This license is a modified version of the GNU General Public License copyright (C) 1989, 1991 Free Software Foundation, Inc. made with their permission. Section 2(d) has been added to cover use of software over a computer network.
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the Affero General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This Public License applies to most of Affero's software and to any other program whose authors commit to using it. (Some other Affero software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. This General Public License is designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this Affero General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
d) If the Program as you received it is intended to interact with users through a computer network and if, in the version you received, any user interacting with the Program was given the opportunity to request transmission to that user of the Program's complete source code, you must not remove that facility from your modified version of the Program or work based on the Program, and must offer an equivalent opportunity for all users interacting with your Program through a computer network to request immediate transmission by HTTP of the complete source code of your modified version or other derivative work.
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
9. Affero Inc. may publish revised and/or new versions of the Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by Affero, Inc. If the Program does not specify a version number of this License, you may choose any version ever published by Affero, Inc.
You may also choose to redistribute modified versions of this program under any version of the Free Software Foundation's GNU General Public License version 3 or higher, so long as that version of the GNU GPL includes terms and conditions substantially equivalent to those of this license.
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by Affero, Inc., write to us; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

5
README.md Normal file
View file

@ -0,0 +1,5 @@
# Dalamud
FFXIV Hooking framework for [FFXIVQuickLauncher](https://github.com/goaaats/FFXIVQuickLauncher).
Thanks to Mino, whose work has made this possible!

BIN
Resources/EasyHook32.dll Normal file

Binary file not shown.

BIN
Resources/EasyHook32Svc.exe Normal file

Binary file not shown.

BIN
Resources/EasyHook64.dll Normal file

Binary file not shown.

BIN
Resources/EasyHook64Svc.exe Normal file

Binary file not shown.

BIN
Resources/EasyLoad32.dll Normal file

Binary file not shown.

BIN
Resources/EasyLoad64.dll Normal file

Binary file not shown.

0
docs/.nojekyll Normal file
View file

View file

@ -0,0 +1,208 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class EnumExtensions
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class EnumExtensions
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.EnumExtensions">
<h1 id="Dalamud_Game_Chat_EnumExtensions" data-uid="Dalamud.Game.Chat.EnumExtensions" class="text-break">Class EnumExtensions
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">EnumExtensions</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_EnumExtensions_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static class EnumExtensions</code></pre>
</div>
<h3 id="methods">Methods
</h3>
<a id="Dalamud_Game_Chat_EnumExtensions_GetAttribute_" data-uid="Dalamud.Game.Chat.EnumExtensions.GetAttribute*"></a>
<h4 id="Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_" data-uid="Dalamud.Game.Chat.EnumExtensions.GetAttribute``1(System.Enum)">GetAttribute&lt;TAttribute&gt;(Enum)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static TAttribute GetAttribute&lt;TAttribute&gt;(this Enum value)
where TAttribute : Attribute</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Enum</span></td>
<td><span class="parametername">value</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">TAttribute</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="typeParameters">Type Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="parametername">TAttribute</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,155 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Enum SeString.IntegerType
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum SeString.IntegerType
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.SeString.IntegerType">
<h1 id="Dalamud_Game_Chat_SeString_IntegerType" data-uid="Dalamud.Game.Chat.SeString.IntegerType" class="text-break">Enum SeString.IntegerType
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_SeString_IntegerType_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public enum IntegerType</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<thead>
<tbody>
<tr>
<td id="Dalamud_Game_Chat_SeString_IntegerType_Byte">Byte</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_SeString_IntegerType_ByteTimes256">ByteTimes256</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_SeString_IntegerType_Int16">Int16</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_SeString_IntegerType_Int24">Int24</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_SeString_IntegerType_Int32">Int32</td>
<td></td>
</tr>
</tbody>
</thead></thead></table>
<h3 id="extensionmethods">Extension Methods</h3>
<div>
<a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html#Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_">EnumExtensions.GetAttribute&lt;TAttribute&gt;()</a>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,139 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Enum SeString.PlayerLinkType
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum SeString.PlayerLinkType
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.SeString.PlayerLinkType">
<h1 id="Dalamud_Game_Chat_SeString_PlayerLinkType" data-uid="Dalamud.Game.Chat.SeString.PlayerLinkType" class="text-break">Enum SeString.PlayerLinkType
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_SeString_PlayerLinkType_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public enum PlayerLinkType</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<thead>
<tbody>
<tr>
<td id="Dalamud_Game_Chat_SeString_PlayerLinkType_ItemLink">ItemLink</td>
<td></td>
</tr>
</tbody>
</thead></thead></table>
<h3 id="extensionmethods">Extension Methods</h3>
<div>
<a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html#Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_">EnumExtensions.GetAttribute&lt;TAttribute&gt;()</a>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,200 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class SeString.SeStringPayloadContainer
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class SeString.SeStringPayloadContainer
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadContainer">
<h1 id="Dalamud_Game_Chat_SeString_SeStringPayloadContainer" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadContainer" class="text-break">Class SeString.SeStringPayloadContainer
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">SeString.SeStringPayloadContainer</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_SeString_SeStringPayloadContainer_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class SeStringPayloadContainer</code></pre>
</div>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_Chat_SeString_SeStringPayloadContainer_Param1_" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadContainer.Param1*"></a>
<h4 id="Dalamud_Game_Chat_SeString_SeStringPayloadContainer_Param1" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadContainer.Param1">Param1</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public object Param1 { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Object</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_SeString_SeStringPayloadContainer_Type_" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadContainer.Type*"></a>
<h4 id="Dalamud_Game_Chat_SeString_SeStringPayloadContainer_Type" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadContainer.Type">Type</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public SeString.SeStringPayloadType Type { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.Chat.SeString.SeStringPayloadType.html">SeString.SeStringPayloadType</a></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,139 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Enum SeString.SeStringPayloadType
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum SeString.SeStringPayloadType
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadType">
<h1 id="Dalamud_Game_Chat_SeString_SeStringPayloadType" data-uid="Dalamud.Game.Chat.SeString.SeStringPayloadType" class="text-break">Enum SeString.SeStringPayloadType
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_SeString_SeStringPayloadType_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public enum SeStringPayloadType</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<thead>
<tbody>
<tr>
<td id="Dalamud_Game_Chat_SeString_SeStringPayloadType_PlayerLink">PlayerLink</td>
<td></td>
</tr>
</tbody>
</thead></thead></table>
<h3 id="extensionmethods">Extension Methods</h3>
<div>
<a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html#Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_">EnumExtensions.GetAttribute&lt;TAttribute&gt;()</a>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,281 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class SeString
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class SeString
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.SeString">
<h1 id="Dalamud_Game_Chat_SeString" data-uid="Dalamud.Game.Chat.SeString" class="text-break">Class SeString
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">SeString</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_SeString_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class SeString</code></pre>
</div>
<h3 id="methods">Methods
</h3>
<a id="Dalamud_Game_Chat_SeString_GetInteger_" data-uid="Dalamud.Game.Chat.SeString.GetInteger*"></a>
<h4 id="Dalamud_Game_Chat_SeString_GetInteger_System_IO_BinaryReader_" data-uid="Dalamud.Game.Chat.SeString.GetInteger(System.IO.BinaryReader)">GetInteger(BinaryReader)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">protected static int GetInteger(BinaryReader input)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.IO.BinaryReader</span></td>
<td><span class="parametername">input</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_SeString_GetInteger_" data-uid="Dalamud.Game.Chat.SeString.GetInteger*"></a>
<h4 id="Dalamud_Game_Chat_SeString_GetInteger_System_IO_BinaryReader_Dalamud_Game_Chat_SeString_IntegerType_" data-uid="Dalamud.Game.Chat.SeString.GetInteger(System.IO.BinaryReader,Dalamud.Game.Chat.SeString.IntegerType)">GetInteger(BinaryReader, SeString.IntegerType)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">protected static int GetInteger(BinaryReader input, SeString.IntegerType type)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.IO.BinaryReader</span></td>
<td><span class="parametername">input</span></td>
<td></td>
</tr>
<tr>
<td><a class="xref" href="Dalamud.Game.Chat.SeString.IntegerType.html">SeString.IntegerType</a></td>
<td><span class="parametername">type</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_SeString_Parse_" data-uid="Dalamud.Game.Chat.SeString.Parse*"></a>
<h4 id="Dalamud_Game_Chat_SeString_Parse_System_String_" data-uid="Dalamud.Game.Chat.SeString.Parse(System.String)">Parse(String)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static (string Output, List&lt;SeString.SeStringPayloadContainer&gt; Payloads)Parse(string input)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td><span class="parametername">input</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.ValueTuple</span>&lt;<span class="xref">System.String</span>, <span class="xref">System.Collections.Generic.List</span>&lt;<a class="xref" href="Dalamud.Game.Chat.SeString.SeStringPayloadContainer.html">SeString.SeStringPayloadContainer</a>&gt;&gt;</td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,275 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class XivChatEntry
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class XivChatEntry
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.XivChatEntry">
<h1 id="Dalamud_Game_Chat_XivChatEntry" data-uid="Dalamud.Game.Chat.XivChatEntry" class="text-break">Class XivChatEntry
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">XivChatEntry</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_XivChatEntry_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public sealed class XivChatEntry</code></pre>
</div>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_Chat_XivChatEntry_Message_" data-uid="Dalamud.Game.Chat.XivChatEntry.Message*"></a>
<h4 id="Dalamud_Game_Chat_XivChatEntry_Message" data-uid="Dalamud.Game.Chat.XivChatEntry.Message">Message</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string Message { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_XivChatEntry_Name_" data-uid="Dalamud.Game.Chat.XivChatEntry.Name*"></a>
<h4 id="Dalamud_Game_Chat_XivChatEntry_Name" data-uid="Dalamud.Game.Chat.XivChatEntry.Name">Name</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string Name { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_XivChatEntry_Parameters_" data-uid="Dalamud.Game.Chat.XivChatEntry.Parameters*"></a>
<h4 id="Dalamud_Game_Chat_XivChatEntry_Parameters" data-uid="Dalamud.Game.Chat.XivChatEntry.Parameters">Parameters</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public IntPtr Parameters { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.IntPtr</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_XivChatEntry_SenderId_" data-uid="Dalamud.Game.Chat.XivChatEntry.SenderId*"></a>
<h4 id="Dalamud_Game_Chat_XivChatEntry_SenderId" data-uid="Dalamud.Game.Chat.XivChatEntry.SenderId">SenderId</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public uint SenderId { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.UInt32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_XivChatEntry_Type_" data-uid="Dalamud.Game.Chat.XivChatEntry.Type*"></a>
<h4 id="Dalamud_Game_Chat_XivChatEntry_Type" data-uid="Dalamud.Game.Chat.XivChatEntry.Type">Type</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public XivChatType Type { get; set; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.Chat.XivChatType.html">XivChatType</a></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,246 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Enum XivChatType
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum XivChatType
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.XivChatType">
<h1 id="Dalamud_Game_Chat_XivChatType" data-uid="Dalamud.Game.Chat.XivChatType" class="text-break">Enum XivChatType
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_XivChatType_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public enum XivChatType : ushort</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<thead>
<tbody>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Alliance">Alliance</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_CrossLinkShell">CrossLinkShell</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_CrossParty">CrossParty</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Debug">Debug</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Echo">Echo</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_FreeCompany">FreeCompany</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_GatheringSystemMessage">GatheringSystemMessage</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls1">Ls1</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls2">Ls2</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls3">Ls3</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls4">Ls4</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls5">Ls5</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls6">Ls6</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls7">Ls7</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Ls8">Ls8</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_None">None</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Notice">Notice</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_NoviceNetwork">NoviceNetwork</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Party">Party</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_PvPTeam">PvPTeam</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Say">Say</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Shout">Shout</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_SystemError">SystemError</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_TellIncoming">TellIncoming</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_TellOutgoing">TellOutgoing</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Urgent">Urgent</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_Chat_XivChatType_Yell">Yell</td>
<td></td>
</tr>
</tbody>
</thead></thead></table>
<h3 id="extensionmethods">Extension Methods</h3>
<div>
<a class="xref" href="Dalamud.Game.Chat.XivChatTypeExtensions.html#Dalamud_Game_Chat_XivChatTypeExtensions_GetDetails_Dalamud_Game_Chat_XivChatType_">XivChatTypeExtensions.GetDetails()</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html#Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_">EnumExtensions.GetAttribute&lt;TAttribute&gt;()</a>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,192 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class XivChatTypeExtensions
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class XivChatTypeExtensions
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.XivChatTypeExtensions">
<h1 id="Dalamud_Game_Chat_XivChatTypeExtensions" data-uid="Dalamud.Game.Chat.XivChatTypeExtensions" class="text-break">Class XivChatTypeExtensions
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">XivChatTypeExtensions</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_XivChatTypeExtensions_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static class XivChatTypeExtensions</code></pre>
</div>
<h3 id="methods">Methods
</h3>
<a id="Dalamud_Game_Chat_XivChatTypeExtensions_GetDetails_" data-uid="Dalamud.Game.Chat.XivChatTypeExtensions.GetDetails*"></a>
<h4 id="Dalamud_Game_Chat_XivChatTypeExtensions_GetDetails_Dalamud_Game_Chat_XivChatType_" data-uid="Dalamud.Game.Chat.XivChatTypeExtensions.GetDetails(Dalamud.Game.Chat.XivChatType)">GetDetails(XivChatType)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public static XivChatTypeInfoAttribute GetDetails(this XivChatType p)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.Chat.XivChatType.html">XivChatType</a></td>
<td><span class="parametername">p</span></td>
<td></td>
</tr>
</tbody>
</table>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.Chat.XivChatTypeInfoAttribute.html">XivChatTypeInfoAttribute</a></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,326 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class XivChatTypeInfoAttribute
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class XivChatTypeInfoAttribute
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat.XivChatTypeInfoAttribute">
<h1 id="Dalamud_Game_Chat_XivChatTypeInfoAttribute" data-uid="Dalamud.Game.Chat.XivChatTypeInfoAttribute" class="text-break">Class XivChatTypeInfoAttribute
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">System.Attribute</span></div>
<div class="level2"><span class="xref">XivChatTypeInfoAttribute</span></div>
</div>
<div classs="implements">
<h5>Implements</h5>
<div><span class="xref">System.Runtime.InteropServices._Attribute</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.MemberInfo, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.MemberInfo, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.MemberInfo)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.MemberInfo, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.MemberInfo, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.MemberInfo, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.MemberInfo, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.MemberInfo, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.ParameterInfo)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.ParameterInfo, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.ParameterInfo, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.ParameterInfo, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.ParameterInfo, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.ParameterInfo, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.ParameterInfo, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.ParameterInfo, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Module, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Module)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Module, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Module, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.Module, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.Module, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.Module, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.Module, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Assembly, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Assembly, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Assembly)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttributes(System.Reflection.Assembly, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.Assembly, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefined(System.Reflection.Assembly, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.Assembly, System.Type)</span>
</div>
<div>
<span class="xref">System.Attribute.GetCustomAttribute(System.Reflection.Assembly, System.Type, System.Boolean)</span>
</div>
<div>
<span class="xref">System.Attribute.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Attribute.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Attribute.Match(System.Object)</span>
</div>
<div>
<span class="xref">System.Attribute.IsDefaultAttribute()</span>
</div>
<div>
<span class="xref">System.Attribute.System.Runtime.InteropServices._Attribute.GetTypeInfoCount(System.UInt32)</span>
</div>
<div>
<span class="xref">System.Attribute.System.Runtime.InteropServices._Attribute.GetTypeInfo(System.UInt32, System.UInt32, System.IntPtr)</span>
</div>
<div>
<span class="xref">System.Attribute.System.Runtime.InteropServices._Attribute.GetIDsOfNames(System.Guid, System.IntPtr, System.UInt32, System.UInt32, System.IntPtr)</span>
</div>
<div>
<span class="xref">System.Attribute.System.Runtime.InteropServices._Attribute.Invoke(System.UInt32, System.Guid, System.UInt32, System.Int16, System.IntPtr, System.IntPtr, System.IntPtr, System.IntPtr)</span>
</div>
<div>
<span class="xref">System.Attribute.TypeId</span>
</div>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.Chat.html">Dalamud.Game.Chat</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_Chat_XivChatTypeInfoAttribute_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class XivChatTypeInfoAttribute : Attribute, _Attribute</code></pre>
</div>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_Chat_XivChatTypeInfoAttribute_DefaultColor_" data-uid="Dalamud.Game.Chat.XivChatTypeInfoAttribute.DefaultColor*"></a>
<h4 id="Dalamud_Game_Chat_XivChatTypeInfoAttribute_DefaultColor" data-uid="Dalamud.Game.Chat.XivChatTypeInfoAttribute.DefaultColor">DefaultColor</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public uint DefaultColor { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.UInt32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_Chat_XivChatTypeInfoAttribute_FancyName_" data-uid="Dalamud.Game.Chat.XivChatTypeInfoAttribute.FancyName*"></a>
<h4 id="Dalamud_Game_Chat_XivChatTypeInfoAttribute_FancyName" data-uid="Dalamud.Game.Chat.XivChatTypeInfoAttribute.FancyName">FancyName</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string FancyName { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="implements">Implements</h3>
<div>
<span class="xref">System.Runtime.InteropServices._Attribute</span>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,137 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Namespace Dalamud.Game.Chat
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Dalamud.Game.Chat
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.Chat">
<h1 id="Dalamud_Game_Chat" data-uid="Dalamud.Game.Chat" class="text-break">Namespace Dalamud.Game.Chat
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="markdown level0 remarks"></div>
<h3 id="classes">Classes
</h3>
<h4><a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html">EnumExtensions</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.SeString.html">SeString</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.SeString.SeStringPayloadContainer.html">SeString.SeStringPayloadContainer</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.XivChatEntry.html">XivChatEntry</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.XivChatTypeExtensions.html">XivChatTypeExtensions</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.XivChatTypeInfoAttribute.html">XivChatTypeInfoAttribute</a></h4>
<section></section>
<h3 id="enums">Enums
</h3>
<h4><a class="xref" href="Dalamud.Game.Chat.SeString.IntegerType.html">SeString.IntegerType</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.SeString.PlayerLinkType.html">SeString.PlayerLinkType</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.SeString.SeStringPayloadType.html">SeString.SeStringPayloadType</a></h4>
<section></section>
<h4><a class="xref" href="Dalamud.Game.Chat.XivChatType.html">XivChatType</a></h4>
<section></section>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,204 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class ChatHandlers
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ChatHandlers
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ChatHandlers">
<h1 id="Dalamud_Game_ChatHandlers" data-uid="Dalamud.Game.ChatHandlers" class="text-break">Class ChatHandlers
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">ChatHandlers</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.html">Dalamud.Game</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ChatHandlers_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class ChatHandlers</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ChatHandlers__ctor_" data-uid="Dalamud.Game.ChatHandlers.#ctor*"></a>
<h4 id="Dalamud_Game_ChatHandlers__ctor_Dalamud_Dalamud_" data-uid="Dalamud.Game.ChatHandlers.#ctor(Dalamud.Dalamud)">ChatHandlers(Dalamud)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public ChatHandlers(Dalamud dalamud)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">Dalamud.Dalamud</span></td>
<td><span class="parametername">dalamud</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ChatHandlers_LastLink_" data-uid="Dalamud.Game.ChatHandlers.LastLink*"></a>
<h4 id="Dalamud_Game_ChatHandlers_LastLink" data-uid="Dalamud.Game.ChatHandlers.LastLink">LastLink</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string LastLink { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,401 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class ActorTable
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ActorTable
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.ActorTable">
<h1 id="Dalamud_Game_ClientState_Actors_ActorTable" data-uid="Dalamud.Game.ClientState.Actors.ActorTable" class="text-break">Class ActorTable
</h1>
<div class="markdown level0 summary"><p>This collection represents the currently spawned FFXIV actors.</p>
</div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">ActorTable</span></div>
</div>
<div classs="implements">
<h5>Implements</h5>
<div><span class="xref">System.Collections.ICollection</span></div>
<div><span class="xref">System.Collections.IEnumerable</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.html">Dalamud.Game.ClientState.Actors</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_ActorTable_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class ActorTable : ICollection, IEnumerable</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ClientState_Actors_ActorTable__ctor_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.#ctor*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable__ctor_Dalamud_Game_ClientState_ClientStateAddressResolver_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.#ctor(Dalamud.Game.ClientState.ClientStateAddressResolver)">ActorTable(ClientStateAddressResolver)</h4>
<div class="markdown level1 summary"><p>Set up the actor table collection.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public ActorTable(ClientStateAddressResolver addressResolver)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">Dalamud.Game.ClientState.ClientStateAddressResolver</span></td>
<td><span class="parametername">addressResolver</span></td>
<td><p>Client state address resolver.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_Item_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.Item*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_Item_System_Int32_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.Item(System.Int32)">Item[Int32]</h4>
<div class="markdown level1 summary"><p>Get an actor at the specified spawn index.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Actor this[int index] { get; }</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td><span class="parametername">index</span></td>
<td><p>Spawn index.</p>
</td>
</tr>
</tbody>
</table>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a></td>
<td><p><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a> at the specified spawn index.</p>
</td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_Length_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.Length*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_Length" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.Length">Length</h4>
<div class="markdown level1 summary"><p>The amount of currently spawned actors.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int Length { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="methods">Methods
</h3>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_GetEnumerator_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.GetEnumerator*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_GetEnumerator" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.GetEnumerator">GetEnumerator()</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public IEnumerator GetEnumerator()</code></pre>
</div>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Collections.IEnumerator</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="eii">Explicit Interface Implementations
</h3>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_CopyTo_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#CopyTo*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_CopyTo_System_Array_System_Int32_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">ICollection.CopyTo(Array, Int32)</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">void ICollection.CopyTo(Array array, int index)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Array</span></td>
<td><span class="parametername">array</span></td>
<td></td>
</tr>
<tr>
<td><span class="xref">System.Int32</span></td>
<td><span class="parametername">index</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_Count_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#Count*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_Count" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#Count">ICollection.Count</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">int ICollection.Count { get; }</code></pre>
</div>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_IsSynchronized_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#IsSynchronized*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_IsSynchronized" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#IsSynchronized">ICollection.IsSynchronized</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">bool ICollection.IsSynchronized { get; }</code></pre>
</div>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Boolean</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_SyncRoot_" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#SyncRoot*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_ActorTable_System_Collections_ICollection_SyncRoot" data-uid="Dalamud.Game.ClientState.Actors.ActorTable.System#Collections#ICollection#SyncRoot">ICollection.SyncRoot</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">object ICollection.SyncRoot { get; }</code></pre>
</div>
<h5 class="returns">Returns</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Object</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="implements">Implements</h3>
<div>
<span class="xref">System.Collections.ICollection</span>
</div>
<div>
<span class="xref">System.Collections.IEnumerable</span>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,208 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Enum ObjectKind
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum ObjectKind
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.ObjectKind">
<h1 id="Dalamud_Game_ClientState_Actors_ObjectKind" data-uid="Dalamud.Game.ClientState.Actors.ObjectKind" class="text-break">Enum ObjectKind
</h1>
<div class="markdown level0 summary"><p>Enum describing possible entity kinds.</p>
</div>
<div class="markdown level0 conceptual"></div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.html">Dalamud.Game.ClientState.Actors</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_ObjectKind_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public enum ObjectKind : byte</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<thead>
<tbody>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Aetheryte">Aetheryte</td>
<td><p>Objects representing aetherytes.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Area">Area</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_BattleNpc">BattleNpc</td>
<td><p>Objects representing battle NPCs.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_CardStand">CardStand</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Companion">Companion</td>
<td><p>Objects representing minions.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Cutscene">Cutscene</td>
<td></td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_EventNpc">EventNpc</td>
<td><p>Objects representing event NPCs.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_EventObj">EventObj</td>
<td><p>Objects representing event objects.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_GatheringPoint">GatheringPoint</td>
<td><p>Objects representing gathering points.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Housing">Housing</td>
<td><p>Objects representing housing objects.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_MountType">MountType</td>
<td><p>Objects representing mounts.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_None">None</td>
<td><p>Invalid actor.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Player">Player</td>
<td><p>Objects representing player characters.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Retainer">Retainer</td>
<td><p>Objects representing retainers.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_ObjectKind_Treasure">Treasure</td>
<td><p>Objects representing treasures.</p>
</td>
</tr>
</tbody>
</thead></thead></table>
<h3 id="extensionmethods">Extension Methods</h3>
<div>
<a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html#Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_">EnumExtensions.GetAttribute&lt;TAttribute&gt;()</a>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,214 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Struct Position3
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Struct Position3
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Position3">
<h1 id="Dalamud_Game_ClientState_Actors_Position3" data-uid="Dalamud.Game.ClientState.Actors.Position3" class="text-break">Struct Position3
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.ValueType.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.ValueType.GetHashCode()</span>
</div>
<div>
<span class="xref">System.ValueType.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.html">Dalamud.Game.ClientState.Actors</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Position3_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public struct Position3</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<h4 id="Dalamud_Game_ClientState_Actors_Position3_X" data-uid="Dalamud.Game.ClientState.Actors.Position3.X">X</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public float X</code></pre>
</div>
<h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Single</span></td>
<td></td>
</tr>
</tbody>
</table>
<h4 id="Dalamud_Game_ClientState_Actors_Position3_Y" data-uid="Dalamud.Game.ClientState.Actors.Position3.Y">Y</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public float Y</code></pre>
</div>
<h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Single</span></td>
<td></td>
</tr>
</tbody>
</table>
<h4 id="Dalamud_Game_ClientState_Actors_Position3_Z" data-uid="Dalamud.Game.ClientState.Actors.Position3.Z">Z</h4>
<div class="markdown level1 summary"></div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public float Z</code></pre>
</div>
<h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Single</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,235 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class ClassJob
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class ClassJob
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob">
<h1 id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob" class="text-break">Class ClassJob
</h1>
<div class="markdown level0 summary"><p>This object represents a world a character can reside on.</p>
</div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">ClassJob</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.Resolvers.html">Dalamud.Game.ClientState.Actors.Resolvers</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class ClassJob</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob__ctor_" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.#ctor*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob__ctor_System_Byte_" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.#ctor(System.Byte)">ClassJob(Byte)</h4>
<div class="markdown level1 summary"><p>Set up the ClassJob resolver with the provided ID.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public ClassJob(byte id)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Byte</span></td>
<td><span class="parametername">id</span></td>
<td><p>The ID of the world.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="fields">Fields
</h3>
<h4 id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob_Id" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.Id">Id</h4>
<div class="markdown level1 summary"><p>ID of the ClassJob.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public readonly int Id</code></pre>
</div>
<h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob_Name_" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.Name*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Resolvers_ClassJob_Name" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.Name">Name</h4>
<div class="markdown level1 summary"><p>Name of the ClassJob.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string Name { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,235 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class World
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class World
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World">
<h1 id="Dalamud_Game_ClientState_Actors_Resolvers_World" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World" class="text-break">Class World
</h1>
<div class="markdown level0 summary"><p>This object represents a world a character can reside on.</p>
</div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">World</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.Resolvers.html">Dalamud.Game.ClientState.Actors.Resolvers</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Resolvers_World_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class World</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ClientState_Actors_Resolvers_World__ctor_" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World.#ctor*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Resolvers_World__ctor_System_Byte_" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World.#ctor(System.Byte)">World(Byte)</h4>
<div class="markdown level1 summary"><p>Set up the world resolver with the provided ID.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public World(byte id)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Byte</span></td>
<td><span class="parametername">id</span></td>
<td><p>The ID of the world.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="fields">Fields
</h3>
<h4 id="Dalamud_Game_ClientState_Actors_Resolvers_World_Id" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World.Id">Id</h4>
<div class="markdown level1 summary"><p>ID of the world.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public readonly int Id</code></pre>
</div>
<h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ClientState_Actors_Resolvers_World_Name_" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World.Name*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Resolvers_World_Name" data-uid="Dalamud.Game.ClientState.Actors.Resolvers.World.Name">Name</h4>
<div class="markdown level1 summary"><p>Name of the world.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string Name { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,121 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Namespace Dalamud.Game.ClientState.Actors.Resolvers
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Namespace Dalamud.Game.ClientState.Actors.Resolvers
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Resolvers">
<h1 id="Dalamud_Game_ClientState_Actors_Resolvers" data-uid="Dalamud.Game.ClientState.Actors.Resolvers" class="text-break">Namespace Dalamud.Game.ClientState.Actors.Resolvers
</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="markdown level0 remarks"></div>
<h3 id="classes">Classes
</h3>
<h4><a class="xref" href="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.html">ClassJob</a></h4>
<section><p>This object represents a world a character can reside on.</p>
</section>
<h4><a class="xref" href="Dalamud.Game.ClientState.Actors.Resolvers.World.html">World</a></h4>
<section><p>This object represents a world a character can reside on.</p>
</section>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,314 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class Actor
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class Actor
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor">
<h1 id="Dalamud_Game_ClientState_Actors_Types_Actor" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor" class="text-break">Class Actor
</h1>
<div class="markdown level0 summary"><p>This class represents a basic FFXIV actor.</p>
</div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><span class="xref">Actor</span></div>
<div class="level2"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html">Chara</a></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.html">Dalamud.Game.ClientState.Actors.Types</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Types_Actor_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class Actor</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ClientState_Actors_Types_Actor__ctor_" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.#ctor*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Actor__ctor_Dalamud_Game_ClientState_Structs_Actor_" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.#ctor(Dalamud.Game.ClientState.Structs.Actor)">Actor(Actor)</h4>
<div class="markdown level1 summary"><p>Initialize a representation of a basic FFXIV actor.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Actor(Actor actorStruct)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Structs.Actor.html">Actor</a></td>
<td><span class="parametername">actorStruct</span></td>
<td><p>The memory representation of the base actor.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="fields">Fields
</h3>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Actor_actorStruct" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.actorStruct">actorStruct</h4>
<div class="markdown level1 summary"><p>The memory representation of the base actor.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">protected Actor actorStruct</code></pre>
</div>
<h5 class="fieldValue">Field Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Structs.Actor.html">Actor</a></td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ClientState_Actors_Types_Actor_ActorId_" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.ActorId*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Actor_ActorId" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.ActorId">ActorId</h4>
<div class="markdown level1 summary"><p>Actor ID of this <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a>.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int ActorId { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Actor_Name_" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.Name*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Actor_Name" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.Name">Name</h4>
<div class="markdown level1 summary"><p>Displayname of this <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a>.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public string Name { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.String</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Actor_ObjectKind_" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.ObjectKind*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Actor_ObjectKind" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.ObjectKind">ObjectKind</h4>
<div class="markdown level1 summary"><p>Entity kind of this <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a>. See <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_ObjectKind">ObjectKind</a> for possible values.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public ObjectKind ObjectKind { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Actors.ObjectKind.html">ObjectKind</a></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Actor_Position_" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.Position*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Actor_Position" data-uid="Dalamud.Game.ClientState.Actors.Types.Actor.Position">Position</h4>
<div class="markdown level1 summary"><p>Position of this <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a>.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Position3 Position { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Actors.Position3.html">Position3</a></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,356 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class Chara
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class Chara
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara">
<h1 id="Dalamud_Game_ClientState_Actors_Types_Chara" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara" class="text-break">Class Chara
</h1>
<div class="markdown level0 summary"><p>This class represents the base for non-static entities.</p>
</div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a></div>
<div class="level2"><span class="xref">Chara</span></div>
<div class="level3"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.Npc.html">Npc</a></div>
<div class="level3"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.PlayerCharacter.html">PlayerCharacter</a></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_actorStruct">Actor.actorStruct</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_Position">Actor.Position</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_Name">Actor.Name</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_ActorId">Actor.ActorId</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_ObjectKind">Actor.ObjectKind</a>
</div>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.html">Dalamud.Game.ClientState.Actors.Types</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Types_Chara_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class Chara : Actor</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara__ctor_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.#ctor*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara__ctor_Dalamud_Game_ClientState_Structs_Actor_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.#ctor(Dalamud.Game.ClientState.Structs.Actor)">Chara(Actor)</h4>
<div class="markdown level1 summary"><p>Set up a new Chara with the provided memory representation.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public Chara(Actor actorStruct)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Structs.Actor.html">Actor</a></td>
<td><span class="parametername">actorStruct</span></td>
<td><p>The memory representation of the base actor.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara_ClassJob_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.ClassJob*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara_ClassJob" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.ClassJob">ClassJob</h4>
<div class="markdown level1 summary"><p>The ClassJob of this Chara.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public ClassJob ClassJob { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.html">ClassJob</a></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara_CurrentHp_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.CurrentHp*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara_CurrentHp" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.CurrentHp">CurrentHp</h4>
<div class="markdown level1 summary"><p>The current HP of this Chara.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int CurrentHp { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara_CurrentMp_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.CurrentMp*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara_CurrentMp" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.CurrentMp">CurrentMp</h4>
<div class="markdown level1 summary"><p>The current MP of this Chara.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int CurrentMp { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara_Level_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.Level*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara_Level" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.Level">Level</h4>
<div class="markdown level1 summary"><p>The level of this Chara.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public byte Level { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Byte</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara_MaxHp_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.MaxHp*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara_MaxHp" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.MaxHp">MaxHp</h4>
<div class="markdown level1 summary"><p>The maximum HP of this Chara.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int MaxHp { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_Chara_MaxMp_" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.MaxMp*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_Chara_MaxMp" data-uid="Dalamud.Game.ClientState.Actors.Types.Chara.MaxMp">MaxMp</h4>
<div class="markdown level1 summary"><p>The maximum MP of this Chara.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int MaxMp { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,273 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Class BattleNpc
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Class BattleNpc
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc">
<h1 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc" class="text-break">Class BattleNpc
</h1>
<div class="markdown level0 summary"><p>This class represents a battle NPC.</p>
</div>
<div class="markdown level0 conceptual"></div>
<div class="inheritance">
<h5>Inheritance</h5>
<div class="level0"><span class="xref">System.Object</span></div>
<div class="level1"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html">Actor</a></div>
<div class="level2"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html">Chara</a></div>
<div class="level3"><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.Npc.html">Npc</a></div>
<div class="level4"><span class="xref">BattleNpc</span></div>
</div>
<div class="inheritedMembers">
<h5>Inherited Members</h5>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.Npc.html#Dalamud_Game_ClientState_Actors_Types_NonPlayer_Npc_DataId">Npc.DataId</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html#Dalamud_Game_ClientState_Actors_Types_Chara_Level">Chara.Level</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html#Dalamud_Game_ClientState_Actors_Types_Chara_ClassJob">Chara.ClassJob</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html#Dalamud_Game_ClientState_Actors_Types_Chara_CurrentHp">Chara.CurrentHp</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html#Dalamud_Game_ClientState_Actors_Types_Chara_MaxHp">Chara.MaxHp</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html#Dalamud_Game_ClientState_Actors_Types_Chara_CurrentMp">Chara.CurrentMp</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Chara.html#Dalamud_Game_ClientState_Actors_Types_Chara_MaxMp">Chara.MaxMp</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_actorStruct">Actor.actorStruct</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_Position">Actor.Position</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_Name">Actor.Name</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_ActorId">Actor.ActorId</a>
</div>
<div>
<a class="xref" href="Dalamud.Game.ClientState.Actors.Types.Actor.html#Dalamud_Game_ClientState_Actors_Types_Actor_ObjectKind">Actor.ObjectKind</a>
</div>
<div>
<span class="xref">System.Object.ToString()</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object)</span>
</div>
<div>
<span class="xref">System.Object.Equals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.ReferenceEquals(System.Object, System.Object)</span>
</div>
<div>
<span class="xref">System.Object.GetHashCode()</span>
</div>
<div>
<span class="xref">System.Object.GetType()</span>
</div>
<div>
<span class="xref">System.Object.MemberwiseClone()</span>
</div>
</div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.html">Dalamud.Game.ClientState.Actors.Types.NonPlayer</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public class BattleNpc : Npc</code></pre>
</div>
<h3 id="constructors">Constructors
</h3>
<a id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc__ctor_" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc.#ctor*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc__ctor_Dalamud_Game_ClientState_Structs_Actor_" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc.#ctor(Dalamud.Game.ClientState.Structs.Actor)">BattleNpc(Actor)</h4>
<div class="markdown level1 summary"><p>Set up a new BattleNpc with the provided memory representation.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public BattleNpc(Actor actorStruct)</code></pre>
</div>
<h5 class="parameters">Parameters</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Structs.Actor.html">Actor</a></td>
<td><span class="parametername">actorStruct</span></td>
<td><p>The memory representation of the base actor.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="properties">Properties
</h3>
<a id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc_BattleNpcKind_" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc.BattleNpcKind*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc_BattleNpcKind" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc.BattleNpcKind">BattleNpcKind</h4>
<div class="markdown level1 summary"><p>The BattleNpc <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpcSubKind.html">BattleNpcSubKind</a> of this BattleNpc.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public BattleNpcSubKind BattleNpcKind { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpcSubKind.html">BattleNpcSubKind</a></td>
<td></td>
</tr>
</tbody>
</table>
<a id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc_OwnerId_" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc.OwnerId*"></a>
<h4 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpc_OwnerId" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpc.OwnerId">OwnerId</h4>
<div class="markdown level1 summary"><p>The ID of this BattleNpc's owner.</p>
</div>
<div class="markdown level1 conceptual"></div>
<h5 class="decalaration">Declaration</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public int OwnerId { get; }</code></pre>
</div>
<h5 class="propertyValue">Property Value</h5>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="xref">System.Int32</span></td>
<td></td>
</tr>
</tbody>
</table>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,151 @@
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Enum BattleNpcSubKind
</title>
<meta name="viewport" content="width=device-width">
<meta name="title" content="Enum BattleNpcSubKind
">
<meta name="generator" content="docfx 2.43.1.0">
<link rel="shortcut icon" href="../favicon.ico">
<link rel="stylesheet" href="../styles/docfx.vendor.css">
<link rel="stylesheet" href="../styles/docfx.css">
<link rel="stylesheet" href="../styles/main.css">
<meta property="docfx:navrel" content="../toc.html">
<meta property="docfx:tocrel" content="toc.html">
</head>
<body data-spy="scroll" data-target="#affix" data-offset="120">
<div id="wrapper">
<header>
<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../logo.svg" alt="">
</a>
</div>
<div class="collapse navbar-collapse" id="navbar">
<form class="navbar-form navbar-right" role="search" id="search">
<div class="form-group">
<input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
</div>
</form>
</div>
</div>
</nav>
<div class="subnav navbar navbar-default">
<div class="container hide-when-search" id="breadcrumb">
<ul class="breadcrumb">
<li></li>
</ul>
</div>
</div>
</header>
<div role="main" class="container body-content hide-when-search">
<div class="sidenav hide-when-search">
<a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
<div class="sidetoggle collapse" id="sidetoggle">
<div id="sidetoc"></div>
</div>
</div>
<div class="article row grid-right">
<div class="col-md-10">
<article class="content wrap" id="_content" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpcSubKind">
<h1 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpcSubKind" data-uid="Dalamud.Game.ClientState.Actors.Types.NonPlayer.BattleNpcSubKind" class="text-break">Enum BattleNpcSubKind
</h1>
<div class="markdown level0 summary"><p>Enum describing possible BattleNpc kinds.</p>
</div>
<div class="markdown level0 conceptual"></div>
<h6><strong>Namespace</strong>: <a class="xref" href="Dalamud.Game.ClientState.Actors.Types.NonPlayer.html">Dalamud.Game.ClientState.Actors.Types.NonPlayer</a></h6>
<h6><strong>Assembly</strong>: Dalamud.dll</h6>
<h5 id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpcSubKind_syntax">Syntax</h5>
<div class="codewrapper">
<pre><code class="lang-csharp hljs">public enum BattleNpcSubKind : byte</code></pre>
</div>
<h3 id="fields">Fields
</h3>
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<thead>
<tbody>
<tr>
<td id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpcSubKind_Enemy">Enemy</td>
<td><p>BattleNpc representing a standard enemy.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpcSubKind_None">None</td>
<td><p>Invalid BattleNpc.</p>
</td>
</tr>
<tr>
<td id="Dalamud_Game_ClientState_Actors_Types_NonPlayer_BattleNpcSubKind_Pet">Pet</td>
<td><p>BattleNpc representing a Pet.</p>
</td>
</tr>
</tbody>
</thead></thead></table>
<h3 id="extensionmethods">Extension Methods</h3>
<div>
<a class="xref" href="Dalamud.Game.Chat.EnumExtensions.html#Dalamud_Game_Chat_EnumExtensions_GetAttribute__1_System_Enum_">EnumExtensions.GetAttribute&lt;TAttribute&gt;()</a>
</div>
</article>
</div>
<div class="hidden-sm col-md-2" role="complementary">
<div class="sideaffix">
<div class="contribution">
<ul class="nav">
</ul>
</div>
<nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
<!-- <p><a class="back-to-top" href="#top">Back to top</a><p> -->
</nav>
</div>
</div>
</div>
</div>
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>
</div>
<script type="text/javascript" src="../styles/docfx.vendor.js"></script>
<script type="text/javascript" src="../styles/docfx.js"></script>
<script type="text/javascript" src="../styles/main.js"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more