Skip to content

Commit f8abb3f

Browse files
ccggzz123@aliyun.comccggzz123@aliyun.com
authored andcommitted
Merge branch 'master' of https://github.com/Perfare/AssetStudio
2 parents 446eeb2 + 50485a9 commit f8abb3f

File tree

201 files changed

+17130
-11534
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

201 files changed

+17130
-11534
lines changed

.github/workflows/build.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: AssetStudioBuild
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
workflow_dispatch:
10+
11+
jobs:
12+
build:
13+
runs-on: windows-latest
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
- uses: microsoft/setup-msbuild@v1.1
18+
19+
- name: Download FBX SDK
20+
run: |
21+
md fbx
22+
cd fbx
23+
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_win.exe" -OutFile "fbxsdk.exe"
24+
Start-Process -FilePath "fbxsdk.exe" /S -Wait
25+
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_pdbs.exe" -OutFile "fbxpdb.exe"
26+
Start-Process -FilePath "fbxpdb.exe" /S -Wait
27+
cd ..
28+
29+
- name: Nuget Restore
30+
run: nuget restore
31+
32+
- name: Build .Net472
33+
run: msbuild /p:Configuration=Release /p:TargetFramework=net472 /verbosity:minimal
34+
35+
- name: Build .Net5
36+
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net5.0-windows /p:SelfContained=false /verbosity:minimal
37+
38+
- name: Build .Net6
39+
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net6.0-windows /p:SelfContained=false /verbosity:minimal
40+
41+
- name: Upload .Net472 Artifact
42+
uses: actions/upload-artifact@v2
43+
with:
44+
name: AssetStudio.net472
45+
path: AssetStudioGUI/bin/Release/net472
46+
47+
- name: Upload .Net5 Artifact
48+
uses: actions/upload-artifact@v2
49+
with:
50+
name: AssetStudio.net5
51+
path: AssetStudioGUI/bin/Release/net5.0-windows/publish
52+
53+
- name: Upload .Net6 Artifact
54+
uses: actions/upload-artifact@v2
55+
with:
56+
name: AssetStudio.net6
57+
path: AssetStudioGUI/bin/Release/net6.0-windows/publish
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
5+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
6+
<Version>0.16.0.0</Version>
7+
<AssemblyVersion>0.16.0.0</AssemblyVersion>
8+
<FileVersion>0.16.0.0</FileVersion>
9+
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
10+
<DebugType>embedded</DebugType>
11+
</PropertyGroup>
12+
13+
</Project>

AssetStudio.PInvoke/DllLoader.cs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Runtime.InteropServices;
6+
7+
namespace AssetStudio.PInvoke
8+
{
9+
public static class DllLoader
10+
{
11+
12+
public static void PreloadDll(string dllName)
13+
{
14+
var dllDir = GetDirectedDllDirectory();
15+
16+
// Not using OperatingSystem.Platform.
17+
// See: https://www.mono-project.com/docs/faq/technical/#how-to-detect-the-execution-platform
18+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
19+
{
20+
Win32.LoadDll(dllDir, dllName);
21+
}
22+
else
23+
{
24+
Posix.LoadDll(dllDir, dllName);
25+
}
26+
}
27+
28+
private static string GetDirectedDllDirectory()
29+
{
30+
var localPath = Process.GetCurrentProcess().MainModule.FileName;
31+
var localDir = Path.GetDirectoryName(localPath);
32+
33+
var subDir = Environment.Is64BitProcess ? "x64" : "x86";
34+
35+
var directedDllDir = Path.Combine(localDir, subDir);
36+
37+
return directedDllDir;
38+
}
39+
40+
private static class Win32
41+
{
42+
43+
internal static void LoadDll(string dllDir, string dllName)
44+
{
45+
var dllFileName = $"{dllName}.dll";
46+
var directedDllPath = Path.Combine(dllDir, dllFileName);
47+
48+
// Specify SEARCH_DLL_LOAD_DIR to load dependent libraries located in the same platform-specific directory.
49+
var hLibrary = LoadLibraryEx(directedDllPath, IntPtr.Zero, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
50+
51+
if (hLibrary == IntPtr.Zero)
52+
{
53+
var errorCode = Marshal.GetLastWin32Error();
54+
var exception = new Win32Exception(errorCode);
55+
56+
throw new DllNotFoundException(exception.Message, exception);
57+
}
58+
}
59+
60+
// HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
61+
// HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
62+
[DllImport("kernel32.dll", SetLastError = true)]
63+
private static extern IntPtr LoadLibraryEx(string lpLibFileName, IntPtr hFile, uint dwFlags);
64+
65+
private const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000;
66+
private const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x100;
67+
68+
}
69+
70+
private static class Posix
71+
{
72+
73+
internal static void LoadDll(string dllDir, string dllName)
74+
{
75+
string dllExtension;
76+
77+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
78+
{
79+
dllExtension = ".so";
80+
}
81+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
82+
{
83+
dllExtension = ".dylib";
84+
}
85+
else
86+
{
87+
throw new NotSupportedException();
88+
}
89+
90+
var dllFileName = $"lib{dllName}{dllExtension}";
91+
var directedDllPath = Path.Combine(dllDir, dllFileName);
92+
93+
const int ldFlags = RTLD_NOW | RTLD_GLOBAL;
94+
var hLibrary = DlOpen(directedDllPath, ldFlags);
95+
96+
if (hLibrary == IntPtr.Zero)
97+
{
98+
var pErrStr = DlError();
99+
// `PtrToStringAnsi` always uses the specific constructor of `String` (see dotnet/core#2325),
100+
// which in turn interprets the byte sequence with system default codepage. On OSX and Linux
101+
// the codepage is UTF-8 so the error message should be handled correctly.
102+
var errorMessage = Marshal.PtrToStringAnsi(pErrStr);
103+
104+
throw new DllNotFoundException(errorMessage);
105+
}
106+
}
107+
108+
// OSX and most Linux OS use LP64 so `int` is still 32-bit even on 64-bit platforms.
109+
// void *dlopen(const char *filename, int flag);
110+
[DllImport("libdl", EntryPoint = "dlopen")]
111+
private static extern IntPtr DlOpen([MarshalAs(UnmanagedType.LPStr)] string fileName, int flags);
112+
113+
// char *dlerror(void);
114+
[DllImport("libdl", EntryPoint = "dlerror")]
115+
private static extern IntPtr DlError();
116+
117+
private const int RTLD_LAZY = 0x1;
118+
private const int RTLD_NOW = 0x2;
119+
private const int RTLD_GLOBAL = 0x100;
120+
121+
}
122+
123+
}
124+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Text;
4+
using Microsoft.Win32.SafeHandles;
5+
6+
namespace AssetStudio.PInvoke
7+
{
8+
// Generally the technique from Steamworks.NET
9+
public class Utf8StringHandle : SafeHandleZeroOrMinusOneIsInvalid
10+
{
11+
12+
static Utf8StringHandle()
13+
{
14+
Utf8 = new UTF8Encoding(false);
15+
}
16+
17+
public Utf8StringHandle(string str)
18+
: base(true)
19+
{
20+
IntPtr buffer;
21+
22+
if (str == null)
23+
{
24+
buffer = IntPtr.Zero;
25+
}
26+
else
27+
{
28+
if (str.Length == 0)
29+
{
30+
buffer = Marshal.AllocHGlobal(1);
31+
32+
unsafe
33+
{
34+
*(byte*)buffer = 0;
35+
}
36+
}
37+
else
38+
{
39+
var strlen = Utf8.GetByteCount(str);
40+
var strBuffer = new byte[strlen + 1];
41+
42+
Utf8.GetBytes(str, 0, str.Length, strBuffer, 0);
43+
44+
buffer = Marshal.AllocHGlobal(strBuffer.Length);
45+
46+
Marshal.Copy(strBuffer, 0, buffer, strBuffer.Length);
47+
}
48+
}
49+
50+
SetHandle(buffer);
51+
}
52+
53+
public static string ReadUtf8StringFromPointer(IntPtr lpstr)
54+
{
55+
if (lpstr == IntPtr.Zero || lpstr == new IntPtr(-1))
56+
{
57+
return null;
58+
}
59+
60+
var byteCount = 0;
61+
62+
unsafe
63+
{
64+
var p = (byte*)lpstr.ToPointer();
65+
66+
while (*p != 0)
67+
{
68+
byteCount += 1;
69+
p += 1;
70+
}
71+
}
72+
73+
if (byteCount == 0)
74+
{
75+
return string.Empty;
76+
}
77+
78+
var strBuffer = new byte[byteCount];
79+
80+
Marshal.Copy(lpstr, strBuffer, 0, byteCount);
81+
82+
var str = Utf8.GetString(strBuffer);
83+
84+
return str;
85+
}
86+
87+
protected override bool ReleaseHandle()
88+
{
89+
if (!IsInvalid)
90+
{
91+
Marshal.FreeHGlobal(handle);
92+
}
93+
94+
return true;
95+
}
96+
97+
private static readonly UTF8Encoding Utf8;
98+
99+
}
100+
}

0 commit comments

Comments
 (0)