refactor: update to sdk and use DalamudPackager
This commit is contained in:
parent
a3affe916a
commit
d14f3fcd2c
|
@ -34,6 +34,7 @@ bld/
|
|||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
.idea/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@ using System.Linq;
|
|||
|
||||
namespace GoodMemory {
|
||||
public static class ActionTypeExt {
|
||||
private static readonly ActionType[] VALID = (ActionType[])Enum.GetValues(typeof(ActionType));
|
||||
private static readonly ActionType[] Valid = (ActionType[])Enum.GetValues(typeof(ActionType));
|
||||
|
||||
public static bool IsValidAction(ItemAction action) {
|
||||
public static bool IsValidAction(ItemAction? action) {
|
||||
if (action == null || action.RowId == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionType type = (ActionType)action.Type;
|
||||
return VALID.Contains(type);
|
||||
var type = (ActionType)action.Type;
|
||||
return Valid.Contains(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<Project>
|
||||
<Target Name="PackagePlugin" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
|
||||
<DalamudPackager ProjectDir="$(ProjectDir)"
|
||||
OutputPath="$(OutputPath)"
|
||||
AssemblyName="$(AssemblyName)"
|
||||
VersionComponents="3"
|
||||
ManifestType="yaml"
|
||||
MakeZip="true"/>
|
||||
</Target>
|
||||
</Project>
|
|
@ -4,58 +4,57 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace GoodMemory {
|
||||
public class GameFunctions {
|
||||
private readonly Plugin plugin;
|
||||
private Plugin Plugin { get; }
|
||||
|
||||
private delegate byte HasItemActionUnlockedDelegate(long itemActionId);
|
||||
private readonly HasItemActionUnlockedDelegate hasItemActionUnlocked;
|
||||
|
||||
private readonly HasItemActionUnlockedDelegate _hasItemActionUnlocked;
|
||||
|
||||
private delegate byte HasCardDelegate(IntPtr localPlayer, ushort cardId);
|
||||
private readonly HasCardDelegate hasCard;
|
||||
|
||||
private readonly IntPtr cardStaticAddr;
|
||||
private readonly HasCardDelegate _hasCard;
|
||||
|
||||
private readonly IntPtr _cardStaticAddr;
|
||||
|
||||
public GameFunctions(Plugin plugin) {
|
||||
this.plugin = plugin ?? throw new ArgumentNullException(nameof(plugin), "Plugin cannot be null");
|
||||
this.Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin), "Plugin cannot be null");
|
||||
|
||||
IntPtr hasIAUnlockedPtr = plugin.Interface.TargetModuleScanner.ScanText("48 83 EC 28 E8 ?? ?? ?? ?? 48 85 C0 0F 84 ?? ?? ?? ??");
|
||||
IntPtr hasCardPtr = plugin.Interface.TargetModuleScanner.ScanText("40 53 48 83 EC 20 48 8B D9 66 85 D2 74 ??");
|
||||
this.cardStaticAddr = plugin.Interface.TargetModuleScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 74 ?? 48 8B 53 ?? 48 8D 4B ?? 48 83 C2 0C 48 8D 14 ?? E8 ?? ?? ?? ?? 40 FE C7 40 3A FD 72 ?? 48 8B 5C 24 ??");
|
||||
var hasIaUnlockedPtr = plugin.Interface.TargetModuleScanner.ScanText("48 83 EC 28 E8 ?? ?? ?? ?? 48 85 C0 0F 84 ?? ?? ?? ??");
|
||||
var hasCardPtr = plugin.Interface.TargetModuleScanner.ScanText("40 53 48 83 EC 20 48 8B D9 66 85 D2 74 ??");
|
||||
this._cardStaticAddr = plugin.Interface.TargetModuleScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 74 ?? 48 8B 53 ?? 48 8D 4B ?? 48 83 C2 0C 48 8D 14 ?? E8 ?? ?? ?? ?? 40 FE C7 40 3A FD 72 ?? 48 8B 5C 24 ??");
|
||||
|
||||
if (hasIAUnlockedPtr == IntPtr.Zero || hasCardPtr == IntPtr.Zero || this.cardStaticAddr == IntPtr.Zero) {
|
||||
if (hasIaUnlockedPtr == IntPtr.Zero || hasCardPtr == IntPtr.Zero || this._cardStaticAddr == IntPtr.Zero) {
|
||||
throw new ApplicationException("Could not get pointers for game functions");
|
||||
}
|
||||
|
||||
this.hasItemActionUnlocked = Marshal.GetDelegateForFunctionPointer<HasItemActionUnlockedDelegate>(hasIAUnlockedPtr);
|
||||
this.hasCard = Marshal.GetDelegateForFunctionPointer<HasCardDelegate>(hasCardPtr);
|
||||
this._hasItemActionUnlocked = Marshal.GetDelegateForFunctionPointer<HasItemActionUnlockedDelegate>(hasIaUnlockedPtr);
|
||||
this._hasCard = Marshal.GetDelegateForFunctionPointer<HasCardDelegate>(hasCardPtr);
|
||||
}
|
||||
|
||||
public bool HasAcquired(Item item) {
|
||||
ItemAction action = item.ItemAction.Value;
|
||||
var action = item.ItemAction.Value;
|
||||
|
||||
if (action == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionType type = (ActionType)action.Type;
|
||||
var type = (ActionType)action.Type;
|
||||
|
||||
if (type == ActionType.Cards) {
|
||||
uint cardId = item.AdditionalData;
|
||||
TripleTriadCard card = this.plugin.Interface.Data.GetExcelSheet<TripleTriadCard>().GetRow(cardId);
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
return this.HasCard((ushort)card.RowId);
|
||||
if (type != ActionType.Cards) {
|
||||
return this.HasItemActionUnlocked(action.RowId);
|
||||
}
|
||||
|
||||
return this.HasItemActionUnlocked(action.RowId);
|
||||
var cardId = item.AdditionalData;
|
||||
var card = this.Plugin.Interface.Data.GetExcelSheet<TripleTriadCard>().GetRow(cardId);
|
||||
return card != null && this.HasCard((ushort)card.RowId);
|
||||
}
|
||||
|
||||
private bool HasItemActionUnlocked(long itemActionId) {
|
||||
return this.hasItemActionUnlocked(itemActionId) == 1;
|
||||
return this._hasItemActionUnlocked(itemActionId) == 1;
|
||||
}
|
||||
|
||||
private bool HasCard(ushort cardId) {
|
||||
return this.hasCard(this.cardStaticAddr, cardId) == 1;
|
||||
return this._hasCard(this._cardStaticAddr, cardId) == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,64 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2B53DAAE-5F20-4EAF-8BC5-97FCE68C1738}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>GoodMemory</RootNamespace>
|
||||
<AssemblyName>GoodMemory</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Dalamud">
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Dalamud.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lumina">
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Lumina.Excel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.Excel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ActionType.cs" />
|
||||
<Compile Include="GameFunctions.cs" />
|
||||
<Compile Include="Plugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GoodMemory.json" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<LangVersion>8</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<AssemblyVersion>1.0.4</AssemblyVersion>
|
||||
<FileVersion>1.0.4</FileVersion>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Dalamud, Version=5.2.1.1, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Dalamud.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Lumina, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Lumina.Excel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.Excel.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DalamudPackager" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"Author": "ascclemens",
|
||||
"Name": "Good Memory",
|
||||
"Description": "Adds an indicator in item tooltips to show whether you have acquired that item.",
|
||||
"InternalName": "GoodMemory",
|
||||
"AssemblyVersion": "1.0.4",
|
||||
"RepoUrl": "https://git.sr.ht/~jkcclemens/GoodMemory",
|
||||
"ApplicableVersion": "any",
|
||||
"DalamudApiLevel": 2
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
author: ascclemens
|
||||
name: GoodMemory
|
||||
description: |-
|
||||
Adds an indicator in item tooltips to show whether you have acquired that item.
|
||||
|
||||
This indicator is in the item's description near the bottom and only appears for
|
||||
items that are unlockable, such as orchestrion rolls, minions, etc.
|
||||
repo_url: https://git.sr.ht/~jkcclemens/GoodMemory
|
|
@ -9,14 +9,14 @@ using System.Text;
|
|||
|
||||
namespace GoodMemory {
|
||||
public class Plugin : IDalamudPlugin {
|
||||
private bool disposedValue;
|
||||
private bool _disposedValue;
|
||||
|
||||
public string Name => "Good Memory";
|
||||
|
||||
public DalamudPluginInterface Interface { get; private set; }
|
||||
private GameFunctions Functions { get; set; }
|
||||
private readonly IntPtr alloc = Marshal.AllocHGlobal(4096);
|
||||
private Hook<TooltipDelegate> tooltipHook;
|
||||
public DalamudPluginInterface Interface { get; private set; } = null!;
|
||||
private GameFunctions Functions { get; set; } = null!;
|
||||
private readonly IntPtr _alloc = Marshal.AllocHGlobal(4096);
|
||||
private Hook<TooltipDelegate>? _tooltipHook;
|
||||
|
||||
private unsafe delegate IntPtr TooltipDelegate(IntPtr a1, uint** a2, byte*** a3);
|
||||
|
||||
|
@ -27,46 +27,48 @@ namespace GoodMemory {
|
|||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing) {
|
||||
if (!this.disposedValue) {
|
||||
if (disposing) {
|
||||
this.tooltipHook?.Dispose();
|
||||
Marshal.FreeHGlobal(this.alloc);
|
||||
}
|
||||
|
||||
this.disposedValue = true;
|
||||
if (this._disposedValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing) {
|
||||
this._tooltipHook?.Dispose();
|
||||
Marshal.FreeHGlobal(this._alloc);
|
||||
}
|
||||
|
||||
this._disposedValue = true;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void SetUpHook() {
|
||||
IntPtr tooltipPtr = this.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 50 48 8B 42 ??");
|
||||
var tooltipPtr = this.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 50 48 8B 42 ??");
|
||||
if (tooltipPtr == IntPtr.Zero) {
|
||||
throw new ApplicationException("Could not set up tooltip hook because of null pointer");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
this.tooltipHook = new Hook<TooltipDelegate>(tooltipPtr, new TooltipDelegate(this.OnTooltip));
|
||||
this._tooltipHook = new Hook<TooltipDelegate>(tooltipPtr, new TooltipDelegate(this.OnTooltip));
|
||||
}
|
||||
|
||||
this.tooltipHook.Enable();
|
||||
this._tooltipHook.Enable();
|
||||
}
|
||||
|
||||
private unsafe void TooltipLogic(IntPtr a1, uint** a2, byte*** a3) {
|
||||
private unsafe void TooltipLogic(uint** a2, byte*** a3) {
|
||||
// this can be replaced with a mid-func hook when reloaded hooks is in dalamud
|
||||
// but for now, do the same logic the func does and replace the text after
|
||||
uint* v3 = *(a2 + 4);
|
||||
uint v9 = *(v3 + 4);
|
||||
var v3 = *(a2 + 4);
|
||||
var v9 = *(v3 + 4);
|
||||
|
||||
if ((v9 & 2) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong itemId = this.Interface.Framework.Gui.HoveredItem;
|
||||
var itemId = this.Interface.Framework.Gui.HoveredItem;
|
||||
if (itemId > 2_000_000) {
|
||||
return;
|
||||
}
|
||||
|
@ -75,19 +77,19 @@ namespace GoodMemory {
|
|||
itemId -= 1_000_000;
|
||||
}
|
||||
|
||||
Item item = this.Interface.Data.GetExcelSheet<Item>().GetRow((uint)itemId);
|
||||
var item = this.Interface.Data.GetExcelSheet<Item>().GetRow((uint)itemId);
|
||||
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the pointer to the text
|
||||
byte** startPtr = *(a3 + 4) + 13;
|
||||
var startPtr = *(a3 + 4) + 13;
|
||||
// get the text pointer
|
||||
byte* start = *startPtr;
|
||||
var start = *startPtr;
|
||||
|
||||
// work around function being called twice
|
||||
if (start == (byte*)this.alloc) {
|
||||
if (start == (byte*)this._alloc) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -95,7 +97,7 @@ namespace GoodMemory {
|
|||
|
||||
// Faded Copies
|
||||
if (item.FilterGroup == 12 && item.ItemUICategory.Value?.RowId == 94 && item.LevelItem.Value?.RowId == 1) {
|
||||
Item[] recipeResults = this.Interface.Data.GetExcelSheet<Recipe>()
|
||||
var recipeResults = this.Interface.Data.GetExcelSheet<Recipe>()
|
||||
.Where(recipe => recipe.UnkStruct5.Any(ritem => ritem.ItemIngredient == item.RowId))
|
||||
.Select(recipe => recipe.ItemResult.Value)
|
||||
.Where(result => result != null)
|
||||
|
@ -103,16 +105,16 @@ namespace GoodMemory {
|
|||
|
||||
overwrite = ReadString(start);
|
||||
|
||||
foreach (Item result in recipeResults) {
|
||||
ItemAction resultAction = result.ItemAction?.Value;
|
||||
foreach (var result in recipeResults) {
|
||||
var resultAction = result.ItemAction?.Value;
|
||||
if (!ActionTypeExt.IsValidAction(resultAction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Assert(resultAction != null, nameof(resultAction) + " != null");
|
||||
|
||||
uint orchId = resultAction.Data[0];
|
||||
Orchestrion orch = this.Interface.Data.GetExcelSheet<Orchestrion>().GetRow(orchId);
|
||||
uint orchId = resultAction!.Data[0];
|
||||
var orch = this.Interface.Data.GetExcelSheet<Orchestrion>().GetRow(orchId);
|
||||
if (orch == null) {
|
||||
continue;
|
||||
}
|
||||
|
@ -120,7 +122,7 @@ namespace GoodMemory {
|
|||
this.AppendIfAcquired(ref overwrite, result, orch.Name);
|
||||
}
|
||||
} else {
|
||||
ItemAction action = item.ItemAction?.Value;
|
||||
var action = item.ItemAction?.Value;
|
||||
|
||||
if (!ActionTypeExt.IsValidAction(action)) {
|
||||
return;
|
||||
|
@ -134,23 +136,23 @@ namespace GoodMemory {
|
|||
}
|
||||
|
||||
// write our replacement text into our own managed memory (4096 bytes)
|
||||
WriteString((byte*)this.alloc, overwrite, true);
|
||||
WriteString((byte*)this._alloc, overwrite, true);
|
||||
|
||||
// overwrite the original pointer with our own
|
||||
*startPtr = (byte*)this.alloc;
|
||||
*startPtr = (byte*)this._alloc;
|
||||
}
|
||||
|
||||
private unsafe IntPtr OnTooltip(IntPtr a1, uint** a2, byte*** a3) {
|
||||
try {
|
||||
this.TooltipLogic(a1, a2, a3);
|
||||
this.TooltipLogic(a2, a3);
|
||||
} catch (Exception ex) {
|
||||
PluginLog.Error($"Could not modify tooltip:\n{ex.Message}\n{ex.StackTrace}");
|
||||
}
|
||||
|
||||
return this.tooltipHook.Original(a1, a2, a3);
|
||||
return this._tooltipHook!.Original(a1, a2, a3);
|
||||
}
|
||||
|
||||
private void AppendIfAcquired(ref string txt, Item item, string name = null) {
|
||||
private void AppendIfAcquired(ref string txt, Item item, string? name = null) {
|
||||
string yes;
|
||||
string no;
|
||||
string acquired;
|
||||
|
@ -158,7 +160,6 @@ namespace GoodMemory {
|
|||
string parenL;
|
||||
string parenR;
|
||||
switch (this.Interface.ClientState.ClientLanguage) {
|
||||
case Dalamud.ClientLanguage.English:
|
||||
default:
|
||||
acquired = "Acquired";
|
||||
colon = ": ";
|
||||
|
@ -193,18 +194,16 @@ namespace GoodMemory {
|
|||
break;
|
||||
}
|
||||
|
||||
string has = this.Functions.HasAcquired(item) ? yes : no;
|
||||
if (name != null) {
|
||||
txt = $"{txt}\n{acquired}{parenL}{name}{parenR}{colon}{has}";
|
||||
} else {
|
||||
txt = $"{txt}\n{acquired}{colon}{has}";
|
||||
}
|
||||
var has = this.Functions.HasAcquired(item) ? yes : no;
|
||||
txt = name == null
|
||||
? $"{txt}\n{acquired}{colon}{has}"
|
||||
: $"{txt}\n{acquired}{parenL}{name}{parenR}{colon}{has}";
|
||||
}
|
||||
|
||||
private unsafe static string ReadString(byte* ptr) {
|
||||
int offset = 0;
|
||||
var offset = 0;
|
||||
while (true) {
|
||||
byte b = *(ptr + offset);
|
||||
var b = *(ptr + offset);
|
||||
if (b == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -216,8 +215,8 @@ namespace GoodMemory {
|
|||
}
|
||||
|
||||
private unsafe static void WriteString(byte* dst, string s, bool finalise = false) {
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(s);
|
||||
for (int i = 0; i < bytes.Length; i++) {
|
||||
var bytes = Encoding.UTF8.GetBytes(s);
|
||||
for (var i = 0; i < bytes.Length; i++) {
|
||||
*(dst + i) = bytes[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GoodMemory")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("GoodMemory")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2b53daae-5f20-4eaf-8bc5-97fce68c1738")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.4")]
|
||||
[assembly: AssemblyFileVersion("1.0.4")]
|
||||
[assembly: NeutralResourcesLanguage("en-GB")]
|
Loading…
Reference in New Issue