IOS 相关代码迁移,增加新窗口

This commit is contained in:
wuwenbo 2026-06-11 16:14:29 +08:00
parent 5d9c911414
commit 140146f1e3
20 changed files with 1242 additions and 41 deletions

View File

@ -15,7 +15,6 @@ using Logic.Audio;
using Logic.CrashSight; using Logic.CrashSight;
using Logic.Skill; using Logic.Skill;
using RuntimeData; using RuntimeData;
using Steamworks;
using TH1_Core.Events; using TH1_Core.Events;
using TH1_Core.Managers; using TH1_Core.Managers;
using TH1_Logic.Core; using TH1_Logic.Core;

View File

@ -0,0 +1,598 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Logic.Config;
using TH1_Logic.Editor.HybridCLR;
using TH1_Logic.Editor.YooAssetTools;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace TH1_Logic.Editor
{
public sealed class TH1UnifiedBuildWindow : EditorWindow
{
private const string VersionConfigPath = "Assets/BundleResources/DataAssets/VersionConfig.asset";
private const string ProductName = "TOHOTOPIA";
private const string ExeName = "TOHOTOPIA.exe";
private static readonly string[] BaseSharedDefines =
{
"UNITY",
"ENABLE_VIEW",
"NODECANVAS"
};
private static readonly string[] ControlledDefines =
{
"UNITY",
"ENABLE_VIEW",
"NODECANVAS",
"STEAMWORKS_NET",
"STEAM_CHANNEL",
"USE_INPUT",
"ENABLE_SPEEDUP",
"ENABLE_TRAIN",
"ENABLE_AIMODEL",
"GAME_AUTO_DEBUG",
"CHECK_ACTIONDEFFERENCE",
"STEAM_TEST",
"TH1_PLATFORM_PC",
"TH1_PLATFORM_IOS"
};
private VersionConfig _versionConfig;
private Vector2 _scroll;
private int _versionIndex;
private uint _major;
private uint _minor;
private uint _patch;
private uint _fourth;
private BuildPlatformProfile _platform = BuildPlatformProfile.PC;
private PackageProfile _package = PackageProfile.Test;
private bool _prepareBeforeBuild = true;
private bool _buildPlayer = true;
private bool _cleanOutput;
private bool _showAdvanced;
private bool _enableSpeedup;
private bool _enableTrain;
private bool _enableAiModel;
private bool _gameAutoDebug;
private bool _checkActionDifference;
private bool _steamTest;
private string _lastAction = "Ready";
[MenuItem("Tools/TH1/Unified Build Window")]
[MenuItem("Tools/TH1/一体化出包工具")]
public static void Open()
{
var window = GetWindow<TH1UnifiedBuildWindow>("TH1 Unified Build");
window.minSize = new Vector2(680, 620);
window.Show();
}
private void OnEnable()
{
LoadVersionConfig();
ResetReleaseTogglesIfNeeded();
}
private void OnGUI()
{
LoadVersionConfig();
DrawHeader();
_scroll = EditorGUILayout.BeginScrollView(_scroll);
DrawVersionSection();
EditorGUILayout.Space(8);
DrawProfileSection();
EditorGUILayout.Space(8);
DrawSpecialDefinesSection();
EditorGUILayout.Space(8);
DrawActions();
EditorGUILayout.EndScrollView();
}
private void DrawHeader()
{
EditorGUILayout.LabelField("TH1 PC / iOS 一体化出包", EditorStyles.boldLabel);
EditorGUILayout.LabelField("当前 Unity 平台", EditorUserBuildSettings.activeBuildTarget.ToString());
EditorGUILayout.LabelField("上次操作", _lastAction);
if (EditorApplication.isCompiling)
{
EditorGUILayout.HelpBox("Unity 正在编译脚本,等编译结束后再执行切平台或构建。", MessageType.Warning);
}
EditorGUILayout.HelpBox(
"流程:选版本 -> 选平台 -> 选测试/发布 -> 勾特殊功能 -> 一键执行。发布包会关闭所有特殊功能宏iOS 配置不会写入 STEAM_CHANNEL/STEAMWORKS_NET。",
MessageType.Info);
}
private void DrawVersionSection()
{
EditorGUILayout.LabelField("版本", EditorStyles.boldLabel);
if (_versionConfig == null)
{
EditorGUILayout.HelpBox($"找不到或无法创建 {VersionConfigPath}", MessageType.Error);
return;
}
using (new EditorGUILayout.HorizontalScope())
{
_major = (uint)Mathf.Max(0, EditorGUILayout.IntField((int)_major, GUILayout.Width(46)));
EditorGUILayout.LabelField(".", GUILayout.Width(10));
_minor = (uint)Mathf.Max(0, EditorGUILayout.IntField((int)_minor, GUILayout.Width(46)));
EditorGUILayout.LabelField(".", GUILayout.Width(10));
_patch = (uint)Mathf.Max(0, EditorGUILayout.IntField((int)_patch, GUILayout.Width(46)));
EditorGUILayout.LabelField("+", GUILayout.Width(10));
_fourth = (uint)Mathf.Clamp(EditorGUILayout.IntField((int)_fourth, GUILayout.Width(46)), 0, 25);
var versionId = _major * 1000000 + _minor * 10000 + _patch * 100 + _fourth;
using (new EditorGUI.DisabledScope(_versionConfig.GetVersionInfo(versionId) != null))
{
if (GUILayout.Button("创建版本", GUILayout.Width(96)))
{
_versionConfig.CreateNewVersion(_major, _minor, _patch, _fourth);
SortVersions();
_versionIndex = FindVersionIndex(versionId);
SaveVersionConfig();
}
}
}
if (_versionConfig.Versions == null || _versionConfig.Versions.Count == 0)
{
EditorGUILayout.HelpBox("还没有版本号,请先创建一个。", MessageType.Warning);
return;
}
SortVersions();
var labels = _versionConfig.Versions.Select(v => v.FullVersion).ToArray();
_versionIndex = Mathf.Clamp(_versionIndex, 0, labels.Length - 1);
_versionIndex = EditorGUILayout.Popup("打包版本", _versionIndex, labels);
var selected = GetSelectedVersion();
if (selected != null)
{
selected.Description = EditorGUILayout.TextArea(selected.Description, GUILayout.MinHeight(90));
}
}
private void DrawProfileSection()
{
EditorGUILayout.LabelField("平台和包类型", EditorStyles.boldLabel);
var nextPlatform = (BuildPlatformProfile)EditorGUILayout.EnumPopup("平台", _platform);
var nextPackage = (PackageProfile)EditorGUILayout.EnumPopup("包类型", _package);
if (nextPlatform != _platform || nextPackage != _package)
{
_platform = nextPlatform;
_package = nextPackage;
ResetReleaseTogglesIfNeeded();
}
_prepareBeforeBuild = EditorGUILayout.ToggleLeft("构建前执行 HybridCLR + YooAsset 准备流程", _prepareBeforeBuild);
_buildPlayer = EditorGUILayout.ToggleLeft("准备完成后 Build Player", _buildPlayer);
_cleanOutput = EditorGUILayout.ToggleLeft("构建前清空本次输出目录", _cleanOutput);
var group = GetBuildTargetGroup(_platform);
EditorGUILayout.LabelField("目标平台组", group.ToString());
EditorGUILayout.LabelField("目标 BuildTarget", GetBuildTarget(_platform).ToString());
EditorGUILayout.LabelField("脚本后端", GetScriptingBackend(_platform, _package).ToString());
EditorGUILayout.LabelField("输出目录", GetOutputPathPreview());
}
private void DrawSpecialDefinesSection()
{
EditorGUILayout.LabelField("特殊功能", EditorStyles.boldLabel);
using (new EditorGUI.DisabledScope(_package == PackageProfile.Release))
{
_enableSpeedup = EditorGUILayout.ToggleLeft("加速模式 ENABLE_SPEEDUP", _enableSpeedup);
_enableTrain = EditorGUILayout.ToggleLeft("训练模式 ENABLE_TRAIN", _enableTrain);
_enableAiModel = EditorGUILayout.ToggleLeft("AI 模型 ENABLE_AIMODEL", _enableAiModel);
_gameAutoDebug = EditorGUILayout.ToggleLeft("自动战斗 GAME_AUTO_DEBUG", _gameAutoDebug);
_checkActionDifference = EditorGUILayout.ToggleLeft("MapData 变化检查 CHECK_ACTIONDEFFERENCE", _checkActionDifference);
_steamTest = EditorGUILayout.ToggleLeft("Steam 测试窗口 STEAM_TEST", _platform == BuildPlatformProfile.PC && _steamTest);
}
if (_package == PackageProfile.Release)
{
EditorGUILayout.HelpBox("发布包会强制关闭上面所有特殊功能宏。OPS 混淆设置不会被这个窗口自动修改,需要单独确认后再处理。", MessageType.None);
}
}
private void DrawActions()
{
EditorGUILayout.LabelField("执行", EditorStyles.boldLabel);
using (new EditorGUI.DisabledScope(EditorApplication.isCompiling || EditorApplication.isPlayingOrWillChangePlaymode || GetSelectedVersion() == null))
{
if (GUILayout.Button("一键应用配置并出包", GUILayout.Height(42)))
{
RunAction("Apply And Build", ApplyAndRun);
}
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("只应用配置", GUILayout.Height(30)))
{
RunAction("Apply Profile", ApplySelectedProfile);
}
if (GUILayout.Button("只准备热更/AB", GUILayout.Height(30)))
{
RunAction("Prepare Assets", () => TH1MigrationCommandLine.PrepareCurrentPlatform(IsDevelopmentBuild()));
}
}
_showAdvanced = EditorGUILayout.Foldout(_showAdvanced, "高级单项", true);
if (_showAdvanced)
{
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("HybridCLR Generate All"))
{
RunAction("HybridCLR Generate All", TH1HybridCLRBuildTools.GenerateAll);
}
if (GUILayout.Button("Build Hotfix DLL"))
{
RunAction("Build Hotfix DLL", () =>
{
if (!TH1HybridCLRBuildTools.BuildAndCopyHotfixArtifacts(IsDevelopmentBuild()))
throw new Exception("Build hotfix dll failed. See Console for details.");
});
}
}
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button("Build YooAsset AB"))
{
RunAction("Build YooAsset AB", TH1YooAssetBuildTools.BuildBuiltinDefaultPackage);
}
if (GUILayout.Button("打开输出目录"))
{
EditorUtility.RevealInFinder(Path.GetDirectoryName(GetOutputPath()));
}
}
}
}
}
private void ApplyAndRun()
{
ApplySelectedProfile();
if (_prepareBeforeBuild)
{
TH1MigrationCommandLine.PrepareCurrentPlatform(IsDevelopmentBuild());
}
if (_buildPlayer)
{
BuildPlayer();
}
}
private void ApplySelectedProfile()
{
var selected = GetSelectedVersion();
if (selected == null) throw new InvalidOperationException("No build version selected.");
SwitchBuildTargetIfNeeded();
ApplyVersion(selected);
ApplyDefines();
ApplyPlayerSettings();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
private void ApplyVersion(VersionInfo selected)
{
_versionConfig.CurVersionId = selected.VersionId;
PlayerSettings.productName = ProductName;
PlayerSettings.bundleVersion = selected.FullVersion;
SaveVersionConfig();
}
private void ApplyDefines()
{
var group = GetBuildTargetGroup(_platform);
var defines = new HashSet<string>(GetDefines(group), StringComparer.Ordinal);
foreach (var symbol in ControlledDefines)
{
defines.Remove(symbol);
}
foreach (var symbol in BaseSharedDefines)
{
defines.Add(symbol);
}
if (_platform == BuildPlatformProfile.PC)
{
defines.Add("TH1_PLATFORM_PC");
defines.Add("STEAMWORKS_NET");
defines.Add("STEAM_CHANNEL");
}
else
{
defines.Add("TH1_PLATFORM_IOS");
}
if (_package == PackageProfile.Test)
{
defines.Add("USE_INPUT");
AddSpecialDefines(defines);
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defines.OrderBy(s => s)));
}
private void AddSpecialDefines(HashSet<string> defines)
{
if (_enableSpeedup) defines.Add("ENABLE_SPEEDUP");
if (_enableTrain) defines.Add("ENABLE_TRAIN");
if (_enableAiModel) defines.Add("ENABLE_AIMODEL");
if (_gameAutoDebug) defines.Add("GAME_AUTO_DEBUG");
if (_checkActionDifference) defines.Add("CHECK_ACTIONDEFFERENCE");
if (_platform == BuildPlatformProfile.PC && _steamTest) defines.Add("STEAM_TEST");
}
private void ApplyPlayerSettings()
{
var group = GetBuildTargetGroup(_platform);
PlayerSettings.SetScriptingBackend(group, GetScriptingBackend(_platform, _package));
EditorUserBuildSettings.development = IsDevelopmentBuild();
EditorUserBuildSettings.allowDebugging = IsDevelopmentBuild();
PlayerSettings.usePlayerLog = IsDevelopmentBuild();
PlayerSettings.enableInternalProfiler = IsDevelopmentBuild();
if (_platform == BuildPlatformProfile.iOS)
{
PlayerSettings.iOS.targetOSVersionString = "13.0";
}
if (IsDevelopmentBuild())
{
SetStackTrace(StackTraceLogType.ScriptOnly, StackTraceLogType.ScriptOnly, StackTraceLogType.ScriptOnly);
}
else
{
PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.None);
PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.None);
PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.ScriptOnly);
PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.ScriptOnly);
}
}
private static void SetStackTrace(StackTraceLogType log, StackTraceLogType warning, StackTraceLogType error)
{
PlayerSettings.SetStackTraceLogType(LogType.Log, log);
PlayerSettings.SetStackTraceLogType(LogType.Warning, warning);
PlayerSettings.SetStackTraceLogType(LogType.Error, error);
PlayerSettings.SetStackTraceLogType(LogType.Assert, error);
PlayerSettings.SetStackTraceLogType(LogType.Exception, error);
}
private void BuildPlayer()
{
var outputPath = GetOutputPath();
var outputDir = _platform == BuildPlatformProfile.iOS ? outputPath : Path.GetDirectoryName(outputPath);
if (string.IsNullOrEmpty(outputDir)) throw new BuildFailedException("Invalid output path.");
if (_cleanOutput && Directory.Exists(outputDir))
{
var fullOutputDir = Path.GetFullPath(outputDir);
var packRoot = Path.GetFullPath(Path.Combine(GetProjectRoot(), "..", "Pack"));
if (!fullOutputDir.StartsWith(packRoot, StringComparison.OrdinalIgnoreCase))
{
throw new BuildFailedException($"Refuse to clean unexpected output dir: {fullOutputDir}");
}
FileUtil.DeleteFileOrDirectory(fullOutputDir);
}
Directory.CreateDirectory(outputDir);
var scenes = EditorBuildSettings.scenes
.Where(scene => scene.enabled)
.Select(scene => scene.path)
.ToArray();
if (scenes.Length == 0) throw new BuildFailedException("No enabled scenes in EditorBuildSettings.");
var options = new BuildPlayerOptions
{
scenes = scenes,
target = GetBuildTarget(_platform),
targetGroup = GetBuildTargetGroup(_platform),
locationPathName = outputPath,
options = GetBuildOptions()
};
using (TH1MigrationBuildValidationGate.Suppress())
{
var report = BuildPipeline.BuildPlayer(options);
if (report.summary.result != BuildResult.Succeeded)
{
throw new BuildFailedException(
$"Build failed: {report.summary.result}, errors={report.summary.totalErrors}, warnings={report.summary.totalWarnings}");
}
}
Debug.Log($"[TH1.UnifiedBuild] Build succeeded: {outputPath}");
}
private BuildOptions GetBuildOptions()
{
if (!IsDevelopmentBuild()) return BuildOptions.None;
return BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.ConnectWithProfiler;
}
private string GetOutputPath()
{
var selected = GetSelectedVersion();
var version = selected?.FullVersion ?? "NoVersion";
var folder = $"{_platform}_{_package}_{version}";
var root = Path.GetFullPath(Path.Combine(GetProjectRoot(), "..", "Pack", folder));
if (_platform == BuildPlatformProfile.iOS)
{
return root;
}
return Path.Combine(root, ExeName);
}
private string GetOutputPathPreview()
{
var output = GetOutputPath();
return _platform == BuildPlatformProfile.iOS ? output : Path.GetDirectoryName(output);
}
private void SwitchBuildTargetIfNeeded()
{
var target = GetBuildTarget(_platform);
var group = GetBuildTargetGroup(_platform);
if (EditorUserBuildSettings.activeBuildTarget == target) return;
if (!EditorUserBuildSettings.SwitchActiveBuildTarget(group, target))
{
throw new BuildFailedException($"Switch build target failed: {target}");
}
}
private static BuildTarget GetBuildTarget(BuildPlatformProfile platform)
{
return platform == BuildPlatformProfile.iOS ? BuildTarget.iOS : BuildTarget.StandaloneWindows64;
}
private static BuildTargetGroup GetBuildTargetGroup(BuildPlatformProfile platform)
{
return platform == BuildPlatformProfile.iOS ? BuildTargetGroup.iOS : BuildTargetGroup.Standalone;
}
private static ScriptingImplementation GetScriptingBackend(BuildPlatformProfile platform, PackageProfile package)
{
if (platform == BuildPlatformProfile.iOS) return ScriptingImplementation.IL2CPP;
return package == PackageProfile.Release ? ScriptingImplementation.IL2CPP : ScriptingImplementation.Mono2x;
}
private bool IsDevelopmentBuild()
{
return _package == PackageProfile.Test;
}
private VersionInfo GetSelectedVersion()
{
if (_versionConfig?.Versions == null || _versionConfig.Versions.Count == 0) return null;
_versionIndex = Mathf.Clamp(_versionIndex, 0, _versionConfig.Versions.Count - 1);
return _versionConfig.Versions[_versionIndex];
}
private void LoadVersionConfig()
{
if (_versionConfig != null) return;
_versionConfig = AssetDatabase.LoadAssetAtPath<VersionConfig>(VersionConfigPath);
if (_versionConfig == null)
{
var dir = Path.GetDirectoryName(VersionConfigPath);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
_versionConfig = CreateInstance<VersionConfig>();
AssetDatabase.CreateAsset(_versionConfig, VersionConfigPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
SortVersions();
_versionIndex = _versionConfig.CurVersionId == 0 ? 0 : FindVersionIndex(_versionConfig.CurVersionId);
}
private void SaveVersionConfig()
{
EditorUtility.SetDirty(_versionConfig);
AssetDatabase.SaveAssets();
}
private void SortVersions()
{
if (_versionConfig?.Versions == null) return;
_versionConfig.Versions = _versionConfig.Versions.OrderByDescending(v => v.VersionId).ToList();
}
private int FindVersionIndex(uint versionId)
{
if (_versionConfig?.Versions == null) return 0;
for (var i = 0; i < _versionConfig.Versions.Count; i++)
{
if (_versionConfig.Versions[i].VersionId == versionId) return i;
}
return 0;
}
private void ResetReleaseTogglesIfNeeded()
{
if (_package != PackageProfile.Release) return;
_enableSpeedup = false;
_enableTrain = false;
_enableAiModel = false;
_gameAutoDebug = false;
_checkActionDifference = false;
_steamTest = false;
}
private static IEnumerable<string> GetDefines(BuildTargetGroup group)
{
return PlayerSettings.GetScriptingDefineSymbolsForGroup(group)
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim())
.Where(s => !string.IsNullOrEmpty(s));
}
private static string GetProjectRoot()
{
return Directory.GetParent(Application.dataPath)?.FullName ?? Application.dataPath;
}
private void RunAction(string title, Action action)
{
try
{
_lastAction = $"{title} running...";
Repaint();
action();
_lastAction = $"{title} OK";
Debug.Log($"[TH1.UnifiedBuild] {title} OK");
}
catch (Exception e)
{
_lastAction = $"{title} failed: {e.Message}";
Debug.LogError($"[TH1.UnifiedBuild] {title} failed:\n{e}");
}
finally
{
Repaint();
}
}
}
public enum BuildPlatformProfile
{
PC,
iOS
}
public enum PackageProfile
{
Test,
Release
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b7ee1d9bbf743e898610ee7468260ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -34,6 +34,12 @@ namespace TH1_Logic.Net
// 获取在线好友列表 // 获取在线好友列表
public Dictionary<ulong, MemberInfo> GetOnlineFriendsDict(); public Dictionary<ulong, MemberInfo> GetOnlineFriendsDict();
// 获取可展示房间列表
public List<LobbyListInfo> GetLobbyListInfos();
// 刷新房间列表缓存
public void RefreshLobbyListInfo();
// 是否初始化完毕 // 是否初始化完毕
public bool IsInitialized(); public bool IsInitialized();
@ -43,6 +49,9 @@ namespace TH1_Logic.Net
// 举报房间 // 举报房间
public bool ReportLobby(LobbyListInfo lobbyInfo); public bool ReportLobby(LobbyListInfo lobbyInfo);
// 处理收到的房间举报消息
public void OnReceivedLobbyReport(LobbyReportMessage message);
// 踢出成员 // 踢出成员
public void KickMember(ulong memberId); public void KickMember(ulong memberId);
@ -68,6 +77,9 @@ namespace TH1_Logic.Net
// 获取房间所有成员信息 // 获取房间所有成员信息
public MemberInfo GetMemberInfo(ulong steamID); public MemberInfo GetMemberInfo(ulong steamID);
// 获取平台展示名
public string GetSelfDisplayName();
// 获取成员数量 // 获取成员数量
public int GetMemberCount(); public int GetMemberCount();
@ -101,14 +113,24 @@ namespace TH1_Logic.Net
// 发送P2P消息 // 发送P2P消息
public bool SendMessageToPeer(ulong member, byte[] data, bool reliable = true); public bool SendMessageToPeer(ulong member, byte[] data, bool reliable = true);
// 不要求已建立房间内 P2P 连接的直发消息,用于邀请/举报等房间外消息
public bool SendMessageToPeerWithoutConnection(ulong member, byte[] data, bool reliable = true);
// 广播P2P消息 // 广播P2P消息
public bool BroadcastMessage(byte[] data, bool reliable = true); public bool BroadcastMessage(byte[] data, bool reliable = true);
// 检查和某成员的 P2P 连接是否已建立
public bool IsPeerConnected(ulong memberId);
// 获取当前房间ID用于分享 // 获取当前房间ID用于分享
public ulong GetShareableLobbyId(); public ulong GetShareableLobbyId();
// 获取自己是否为隐私状态 // 获取自己是否为隐私状态
public bool IsSelfStatusInvisibleOrOffline(); public bool IsSelfStatusInvisibleOrOffline();
// 平台房间名工具
public string GetDefaultRoomName(string ownerName);
public string FilterRoomName(string roomName);
} }
@ -193,7 +215,16 @@ namespace TH1_Logic.Net
public Dictionary<ulong, MemberInfo> GetOnlineFriendsDict() public Dictionary<ulong, MemberInfo> GetOnlineFriendsDict()
{ {
return null; return new Dictionary<ulong, MemberInfo>();
}
public List<LobbyListInfo> GetLobbyListInfos()
{
return new List<LobbyListInfo>();
}
public void RefreshLobbyListInfo()
{
} }
public void CreateLobby(int maxMembers = 4,bool isPublic = true, string password = "", string roomName = "") public void CreateLobby(int maxMembers = 4,bool isPublic = true, string password = "", string roomName = "")
@ -266,6 +297,16 @@ namespace TH1_Logic.Net
return false; return false;
} }
public bool SendMessageToPeerWithoutConnection(ulong member, byte[] data, bool reliable = true)
{
return false;
}
public bool IsPeerConnected(ulong memberId)
{
return false;
}
public ulong GetShareableLobbyId() public ulong GetShareableLobbyId()
{ {
return 0; return 0;
@ -275,5 +316,24 @@ namespace TH1_Logic.Net
{ {
return false; return false;
} }
public void OnReceivedLobbyReport(LobbyReportMessage message)
{
}
public string GetSelfDisplayName()
{
return string.Empty;
}
public string GetDefaultRoomName(string ownerName)
{
return string.IsNullOrWhiteSpace(ownerName) ? "Default" : ownerName;
}
public string FilterRoomName(string roomName)
{
return roomName ?? string.Empty;
}
} }
} }

View File

@ -6,7 +6,7 @@
*/ */
using TH1_Logic.Steam; using System;
namespace TH1_Logic.Net namespace TH1_Logic.Net
{ {
@ -18,12 +18,23 @@ namespace TH1_Logic.Net
public void Init() public void Init()
{ {
#if UNITY_EDITOR || STEAM_CHANNEL #if STEAM_CHANNEL || STEAMWORKS_NET
Lobby = new SteamLobbyManager(); Lobby = CreateSteamLobby() ?? new LobbyBase();
#else #else
Lobby = new LobbyBase(); Lobby = new LobbyBase();
#endif #endif
Lobby.Init(); Lobby.Init();
} }
#if STEAM_CHANNEL || STEAMWORKS_NET
private static ILobby CreateSteamLobby()
{
var lobbyType = Type.GetType("TH1_Logic.Steam.SteamLobbyManager")
?? Type.GetType("TH1_Logic.Steam.SteamLobbyManager, TH1.Hotfix")
?? Type.GetType("TH1_Logic.Steam.SteamLobbyManager, TH1.Steam.Runtime");
if (lobbyType == null) return null;
return Activator.CreateInstance(lobbyType) as ILobby;
}
#endif
} }
} }

View File

@ -3,7 +3,9 @@ using System.Threading.Tasks;
using Logic.CrashSight; using Logic.CrashSight;
using MemoryPack; using MemoryPack;
using RuntimeData; using RuntimeData;
#if STEAM_CHANNEL || STEAMWORKS_NET
using Steamworks; using Steamworks;
#endif
using TH1_Logic.Collect; using TH1_Logic.Collect;
using TH1_Logic.Config; using TH1_Logic.Config;
using TH1_Logic.Core; using TH1_Logic.Core;
@ -245,6 +247,7 @@ namespace TH1_Logic.Oss
private static bool TryGetSteamId(out string steamId) private static bool TryGetSteamId(out string steamId)
{ {
steamId = ""; steamId = "";
#if STEAM_CHANNEL || STEAMWORKS_NET
try try
{ {
if (!SteamUser.BLoggedOn()) return false; if (!SteamUser.BLoggedOn()) return false;
@ -259,11 +262,15 @@ namespace TH1_Logic.Oss
{ {
return false; return false;
} }
#else
return false;
#endif
} }
private static bool TryGetAuthTicket(out string authTicket) private static bool TryGetAuthTicket(out string authTicket)
{ {
authTicket = null; authTicket = null;
#if STEAM_CHANNEL || STEAMWORKS_NET
try try
{ {
var ticket = new byte[1024]; var ticket = new byte[1024];
@ -283,6 +290,9 @@ namespace TH1_Logic.Oss
LogSystem.LogWarning($"Steam auth ticket unavailable: {ex.Message}"); LogSystem.LogWarning($"Steam auth ticket unavailable: {ex.Message}");
return false; return false;
} }
#else
return false;
#endif
} }
} }
} }

View File

@ -2,7 +2,9 @@ using System;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Logic.CrashSight; using Logic.CrashSight;
#if STEAM_CHANNEL || STEAMWORKS_NET
using Steamworks; using Steamworks;
#endif
using TH1_Logic.Config; using TH1_Logic.Config;
using UnityEngine; using UnityEngine;
using UnityEngine.Networking; using UnityEngine.Networking;
@ -144,6 +146,7 @@ namespace TH1_Logic.Oss
private static string GetSteamAppId() private static string GetSteamAppId()
{ {
#if STEAM_CHANNEL || STEAMWORKS_NET
try try
{ {
var appId = SteamUtils.GetAppID().m_AppId; var appId = SteamUtils.GetAppID().m_AppId;
@ -153,6 +156,9 @@ namespace TH1_Logic.Oss
{ {
return string.Empty; return string.Empty;
} }
#else
return string.Empty;
#endif
} }
} }
} }

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: aabdf2d1799e4f6192d3398f1a1f9290
timeCreated: 1745464912

View File

@ -762,8 +762,7 @@ namespace TH1_Logic.Steam
return; return;
} }
if (LobbyManager.Instance.Lobby is SteamLobbyManager steamLobby) LobbyManager.Instance.Lobby?.OnReceivedLobbyReport(message);
steamLobby.OnReceivedLobbyReport(message);
} }
private void OnReceivedInviteVersionMismatch(InviteVersionMismatchMessage message) private void OnReceivedInviteVersionMismatch(InviteVersionMismatchMessage message)

View File

@ -12,7 +12,6 @@ using Logic.AI;
using Logic.CrashSight; using Logic.CrashSight;
using MemoryPack; using MemoryPack;
using RuntimeData; using RuntimeData;
using Steamworks;
using TH1_Logic.Chat; using TH1_Logic.Chat;
using TH1_Logic.Config; using TH1_Logic.Config;
using TH1_Logic.Core; using TH1_Logic.Core;
@ -57,9 +56,6 @@ namespace TH1_Logic.Steam
{ {
if (lobbyInfo == null || lobbyInfo.OwnerId == 0 || lobbyInfo.LobbyId == 0) return false; if (lobbyInfo == null || lobbyInfo.OwnerId == 0 || lobbyInfo.LobbyId == 0) return false;
var targetId = new CSteamID(lobbyInfo.OwnerId);
if (!targetId.IsValid()) return false;
var data = new InviteVersionMismatchMessage var data = new InviteVersionMismatchMessage
{ {
LobbyId = lobbyInfo.LobbyId, LobbyId = lobbyInfo.LobbyId,
@ -68,8 +64,8 @@ namespace TH1_Logic.Steam
LobbyVersion = lobbyInfo.Version, LobbyVersion = lobbyInfo.Version,
}; };
byte[] messageBytes = NetworkPayloadCodec.Encode(TH1Serialization.Serialize<BaseMessage>(data)); byte[] messageBytes = SerializeForNetwork(data);
if (SimpleP2P.Instance.SendToWithOutConnect(targetId, messageBytes)) return true; if (LobbyManager.Instance.Lobby.SendMessageToPeerWithoutConnection(lobbyInfo.OwnerId, messageBytes)) return true;
LogSystem.LogError($"InviteVersionMismatchMessage: 发送给房主失败 owner={lobbyInfo.OwnerId}, lobby={lobbyInfo.LobbyId}"); LogSystem.LogError($"InviteVersionMismatchMessage: 发送给房主失败 owner={lobbyInfo.OwnerId}, lobby={lobbyInfo.LobbyId}");
return false; return false;
@ -313,8 +309,7 @@ namespace TH1_Logic.Steam
{ {
if (memberId == selfId) continue; if (memberId == selfId) continue;
var target = new CSteamID(memberId); if (!LobbyManager.Instance.Lobby.IsPeerConnected(memberId))
if (!SimpleP2P.Instance.IsConnectedTo(target))
{ {
LogSystem.LogInfo($"UpdateLobbyData deferred until P2P connected: memberId={memberId}"); LogSystem.LogInfo($"UpdateLobbyData deferred until P2P connected: memberId={memberId}");
continue; continue;
@ -330,7 +325,7 @@ namespace TH1_Logic.Steam
if (LobbyManager.Instance.Lobby.IsLobbyOwner()) return false; if (LobbyManager.Instance.Lobby.IsLobbyOwner()) return false;
if (!LobbyManager.Instance.Lobby.IsInLobby()) return false; if (!LobbyManager.Instance.Lobby.IsInLobby()) return false;
var hostId = LobbyManager.Instance.Lobby.GetLobbyOwnerId(); var hostId = LobbyManager.Instance.Lobby.GetLobbyOwnerId();
if (hostId == 0 || !SimpleP2P.Instance.IsConnectedTo(new CSteamID(hostId))) if (hostId == 0 || !LobbyManager.Instance.Lobby.IsPeerConnected(hostId))
{ {
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyDataRequestFailed); NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyDataRequestFailed);
return false; return false;

View File

@ -0,0 +1,21 @@
using MemoryPack;
namespace TH1_Logic.Steam
{
// 房间信息结构。保持命名空间和字段不变,避免影响已有网络消息和 UI 引用。
[MemoryPackable]
public partial class LobbyListInfo
{
public ulong LobbyId;
public ulong OwnerId;
public string OwnerName;
public string RoomName;
public string Version;
public int CurrentPlayers;
public int MaxPlayers;
public int GameState;
public bool HasPassword;
public int ReportCount;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 93f23d875f97403ba1d4cf2afdc2f8c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using System; using System;
#if STEAM_CHANNEL || STEAMWORKS_NET
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Logic.CrashSight; using Logic.CrashSight;
@ -1738,3 +1739,4 @@ namespace TH1_Logic.Steam
} }
} }
} }
#endif

View File

@ -5,7 +5,7 @@
* @Modify: * @Modify:
*/ */
#if STEAM_CHANNEL || STEAMWORKS_NET
using TH1_Logic.Core; using TH1_Logic.Core;
using TH1_Logic.Net; using TH1_Logic.Net;
using UnityEngine; using UnityEngine;
@ -138,4 +138,5 @@ namespace TH1_Logic.Steam
#endif #endif
} }
} }
#endif

View File

@ -1,4 +1,4 @@
#if STEAM_CHANNEL || STEAMWORKS_NET
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -108,6 +108,7 @@ namespace TH1_Logic.Steam
// 房间列表 // 房间列表
private List<LobbyListInfo> _lobbyListInfos; private List<LobbyListInfo> _lobbyListInfos;
public List<LobbyListInfo> LobbyListInfos => _lobbyListInfos; public List<LobbyListInfo> LobbyListInfos => _lobbyListInfos;
public List<LobbyListInfo> GetLobbyListInfos() => _lobbyListInfos;
private readonly HashSet<ulong> _lobbyReporters = new HashSet<ulong>(); private readonly HashSet<ulong> _lobbyReporters = new HashSet<ulong>();
// 事件委托 // 事件委托
@ -1274,6 +1275,21 @@ namespace TH1_Logic.Steam
if (string.IsNullOrEmpty(filteredRoomName)) return "Default"; if (string.IsNullOrEmpty(filteredRoomName)) return "Default";
return BannedWordFilter.Filter(filteredRoomName, BannedTextContext.Name); return BannedWordFilter.Filter(filteredRoomName, BannedTextContext.Name);
} }
string ILobby.GetDefaultRoomName(string ownerName)
{
return GetDefaultRoomName(ownerName);
}
string ILobby.FilterRoomName(string roomName)
{
return FilterRoomName(roomName);
}
public string GetSelfDisplayName()
{
return SelfName;
}
public bool IsInitialized() public bool IsInitialized()
{ {
@ -1797,6 +1813,23 @@ namespace TH1_Logic.Steam
return SimpleP2P.Instance.SendTo(cSteamId, data, reliable); return SimpleP2P.Instance.SendTo(cSteamId, data, reliable);
} }
public bool SendMessageToPeerWithoutConnection(ulong member, byte[] data, bool reliable = true)
{
if (data == null || data.Length == 0)
return ReportP2PSendPrecheckFailed(member, "Trying to send null or empty data");
var targetId = new CSteamID(member);
if (!targetId.IsValid())
return ReportP2PSendPrecheckFailed(member, $"Invalid target member: {member}");
return SimpleP2P.Instance.SendToWithOutConnect(targetId, data, reliable);
}
public bool IsPeerConnected(ulong memberId)
{
if (memberId == 0) return false;
var targetId = new CSteamID(memberId);
return targetId.IsValid() && SimpleP2P.Instance.IsConnectedTo(targetId);
}
// 广播P2P消息 // 广播P2P消息
public bool BroadcastMessage(byte[] data, bool reliable = true) public bool BroadcastMessage(byte[] data, bool reliable = true)
{ {
@ -2129,22 +2162,5 @@ namespace TH1_Logic.Steam
LogSystem.LogInfo("SteamLobbyManager cleaned up"); LogSystem.LogInfo("SteamLobbyManager cleaned up");
} }
} }
// 房间信息结构
[MemoryPackable]
public partial class LobbyListInfo
{
public ulong LobbyId;
public ulong OwnerId;
public string OwnerName;
public string RoomName;
public string Version;
public int CurrentPlayers;
public int MaxPlayers;
public int GameState;
public bool HasPassword;
public int ReportCount;
}
} }
#endif

View File

@ -0,0 +1,145 @@
#if !(STEAM_CHANNEL || STEAMWORKS_NET)
using System;
using System.Collections.Generic;
using Steamworks;
using TH1_Logic.Chat;
using TH1_Logic.Net;
namespace TH1_Logic.Steam
{
public class SteamLobbyManager : LobbyBase
{
public const string LobbyPasswordWrongError = "LobbyPasswordWrong";
public bool IsSteamInitialized => false;
public bool IsloggedIn => false;
public bool IsLobbyInitialized => false;
public string SelfName => GetSelfDisplayName();
public CSteamID SelfID => CSteamID.Nil;
public List<LobbyListInfo> LobbyListInfos => GetLobbyListInfos();
public event Action<CSteamID> OnLobbyCreatedEvent;
public event Action<CSteamID> OnLobbyEnteredEvent;
public event Action<List<CSteamID>> OnLobbyLeftEvent;
public event Action<CSteamID, CSteamID> OnHostChangedEvent;
public event Action<List<CSteamID>> OnMembersChangedEvent;
public event Action<string> OnLobbyErrorEvent;
public event Action<CSteamID> OnMemberJoinedEvent;
public event Action<CSteamID> OnMemberLeftEvent;
public new static string GetDefaultRoomName(string selfName)
{
return string.IsNullOrWhiteSpace(selfName) ? "Default" : $"{selfName} Room";
}
public static string FilterRoomName(string input, int maxLength = 20)
{
if (string.IsNullOrWhiteSpace(input)) return "Default";
var result = input.Trim();
if (result.Length > maxLength) result = result.Substring(0, maxLength);
return BannedWordFilter.Filter(result, BannedTextContext.Name);
}
public string GetRoomName()
{
return "Default";
}
public bool SetRoomName(string roomName)
{
return false;
}
public bool CanCreateLobbyNow(out string reason)
{
reason = "Steam is unavailable on this platform.";
return false;
}
public void SearchPublicLobbies()
{
}
public List<(CSteamID id, string name)> GetOnlineFriends()
{
return new List<(CSteamID, string)>();
}
public CSteamID GetCSteamID(ulong memberId)
{
return CSteamID.Nil;
}
public EPersonaState GetSelfPersonaState()
{
return EPersonaState.k_EPersonaStateOffline;
}
public void RaiseNoSteamError()
{
OnLobbyErrorEvent?.Invoke("Steam is unavailable on this platform.");
}
public void SuppressEventWarnings()
{
_ = OnLobbyCreatedEvent;
_ = OnLobbyEnteredEvent;
_ = OnLobbyLeftEvent;
_ = OnHostChangedEvent;
_ = OnMembersChangedEvent;
_ = OnMemberJoinedEvent;
_ = OnMemberLeftEvent;
}
}
public class SimpleP2P
{
public static SimpleP2P Instance { get; } = new SimpleP2P();
public bool IsInitialized => false;
public event Action<CSteamID> OnPeerConnectedEvent;
public event Action<CSteamID> OnPeerDisconnectedEvent;
public event Action<CSteamID, byte[]> OnMessageReceivedEvent;
public event Action<CSteamID, string> OnMessageSendFailedEvent;
public event Action<string> OnConnectionErrorEvent;
public void Initialize() { }
public void Update() { }
public void PollMessages() { }
public void Cleanup() { }
public void DisconnectAll() { }
public void DisconnectFromPeer(CSteamID steamID) { }
public void MarkExpectedDisconnect(CSteamID steamID) { }
public int GetConnectionCount() => 0;
public bool ConnectToPeer(CSteamID steamID) => false;
public bool IsConnectedTo(CSteamID steamID) => false;
public IEnumerable<CSteamID> GetConnectedPeers() => Array.Empty<CSteamID>();
public bool HasRecentConnectionFailure(float seconds, out string reason)
{
reason = string.Empty;
return false;
}
public bool SendTo(CSteamID target, byte[] data, bool reliable = true, bool ordered = true) => false;
public bool SendToWithOutConnect(CSteamID target, byte[] data, bool reliable = true, bool ordered = true) => false;
public bool CanQueueMessages(IReadOnlyList<CSteamID> targets, int dataLength, out CSteamID failedTarget, out string reason)
{
failedTarget = CSteamID.Nil;
reason = string.Empty;
return targets == null || targets.Count == 0;
}
public void LogDetailedConnectionInfo(CSteamID steamID) { }
public void SuppressEventWarnings()
{
_ = OnPeerConnectedEvent;
_ = OnPeerDisconnectedEvent;
_ = OnMessageReceivedEvent;
_ = OnMessageSendFailedEvent;
_ = OnConnectionErrorEvent;
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6d9854f7e4ff4700b11fc15f41159a9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,291 @@
#if !(STEAM_CHANNEL || STEAMWORKS_NET)
using System;
namespace Steamworks
{
public struct CSteamID : IEquatable<CSteamID>
{
public static readonly CSteamID Nil = new CSteamID(0);
public ulong m_SteamID;
public CSteamID(ulong value)
{
m_SteamID = value;
}
public bool IsValid() => m_SteamID != 0;
public uint GetAccountID() => (uint)(m_SteamID & 0xffffffff);
public bool Equals(CSteamID other) => m_SteamID == other.m_SteamID;
public override bool Equals(object obj) => obj is CSteamID other && Equals(other);
public override int GetHashCode() => m_SteamID.GetHashCode();
public override string ToString() => m_SteamID.ToString();
public static bool operator ==(CSteamID left, CSteamID right) => left.Equals(right);
public static bool operator !=(CSteamID left, CSteamID right) => !left.Equals(right);
}
public struct PublishedFileId_t : IEquatable<PublishedFileId_t>
{
public ulong m_PublishedFileId;
public PublishedFileId_t(ulong value)
{
m_PublishedFileId = value;
}
public bool Equals(PublishedFileId_t other) => m_PublishedFileId == other.m_PublishedFileId;
public override bool Equals(object obj) => obj is PublishedFileId_t other && Equals(other);
public override int GetHashCode() => m_PublishedFileId.GetHashCode();
public override string ToString() => m_PublishedFileId.ToString();
public static bool operator ==(PublishedFileId_t left, PublishedFileId_t right) => left.Equals(right);
public static bool operator !=(PublishedFileId_t left, PublishedFileId_t right) => !left.Equals(right);
}
public struct AppId_t
{
public uint m_AppId;
public AppId_t(uint value)
{
m_AppId = value;
}
}
public struct SteamAPICall_t
{
public ulong m_SteamAPICall;
}
public struct UGCQueryHandle_t
{
public ulong m_UGCQueryHandle;
}
public struct UGCUpdateHandle_t
{
public ulong m_UGCUpdateHandle;
}
public struct SteamNetworkingIdentity
{
public CSteamID SteamID;
public void SetSteamID(CSteamID steamId)
{
SteamID = steamId;
}
}
public enum EResult
{
k_EResultOK = 1,
k_EResultFail = 2,
k_EResultNoConnection = 3,
k_EResultInvalidPassword = 5,
k_EResultLimitExceeded = 25,
k_EResultIgnored = 43,
k_EResultAccessDenied = 15
}
public enum EPersonaState
{
k_EPersonaStateOffline = 0,
k_EPersonaStateOnline = 1,
k_EPersonaStateBusy = 2,
k_EPersonaStateAway = 3,
k_EPersonaStateSnooze = 4,
k_EPersonaStateInvisible = 7
}
public enum ETextFilteringContext
{
k_ETextFilteringContextUnknown = 0,
k_ETextFilteringContextGameContent = 1,
k_ETextFilteringContextChat = 2,
k_ETextFilteringContextName = 3
}
[Flags]
public enum EItemState
{
k_EItemStateNone = 0,
k_EItemStateSubscribed = 1,
k_EItemStateInstalled = 4
}
public enum EItemUpdateStatus
{
k_EItemUpdateStatusInvalid = 0
}
public enum EWorkshopFileType
{
k_EWorkshopFileTypeCommunity = 0
}
public enum ERemoteStoragePublishedFileVisibility
{
k_ERemoteStoragePublishedFileVisibilityPublic = 0
}
public enum EUGCQuery
{
k_EUGCQuery_RankedByPublicationDate = 0
}
public enum EUGCMatchingUGCType
{
k_EUGCMatchingUGCType_Items = 0,
k_EUGCMatchingUGCType_Items_ReadyToUse = 1
}
public enum EUserUGCList
{
k_EUserUGCList_Published = 0
}
public enum EUserUGCListSortOrder
{
k_EUserUGCListSortOrder_CreationOrderDesc = 0
}
public struct SteamUGCDetails_t
{
public PublishedFileId_t m_nPublishedFileId;
public string m_rgchTitle;
public string m_rgchDescription;
public string m_rgchTags;
public uint m_unVotesUp;
public uint m_unVotesDown;
public int m_nFileSize;
public uint m_rtimeCreated;
public uint m_rtimeUpdated;
public ulong m_ulSteamIDOwner;
}
public struct SteamUGCQueryCompleted_t
{
public UGCQueryHandle_t m_handle;
public EResult m_eResult;
public uint m_unNumResultsReturned;
public uint m_unTotalMatchingResults;
}
public struct CreateItemResult_t
{
public EResult m_eResult;
public PublishedFileId_t m_nPublishedFileId;
public bool m_bUserNeedsToAcceptWorkshopLegalAgreement;
}
public struct SubmitItemUpdateResult_t
{
public EResult m_eResult;
public bool m_bUserNeedsToAcceptWorkshopLegalAgreement;
}
public struct RemoteStorageSubscribePublishedFileResult_t
{
public EResult m_eResult;
public PublishedFileId_t m_nPublishedFileId;
}
public struct RemoteStorageUnsubscribePublishedFileResult_t
{
public EResult m_eResult;
public PublishedFileId_t m_nPublishedFileId;
}
public sealed class CallResult<T>
{
public static CallResult<T> Create(Action<T, bool> callback) => new CallResult<T>();
public void Set(SteamAPICall_t apiCall) { }
public void Set(SteamAPICall_t apiCall, Action<T, bool> callback) { }
}
public static class CallbackDispatcher
{
public static bool IsInitialized => false;
}
public static class SteamAPI
{
public static bool IsSteamRunning() => false;
public static void RunCallbacks() { }
}
public static class SteamUtils
{
public static AppId_t GetAppID() => new AppId_t(0);
public static bool InitFilterText(uint filterOptions = 0) => false;
public static int FilterText(ETextFilteringContext context, CSteamID sourceSteamId, string input, out string filtered, uint filteredSize)
{
filtered = input;
return -1;
}
}
public static class SteamUser
{
public static bool BLoggedOn() => false;
public static CSteamID GetSteamID() => CSteamID.Nil;
public static uint GetAuthSessionTicket(byte[] ticket, int maxTicket, out uint ticketSize, ref SteamNetworkingIdentity identity)
{
ticketSize = 0;
return 0;
}
}
public static class SteamFriends
{
public static string GetPersonaName() => string.Empty;
public static bool RequestUserInformation(CSteamID steamId, bool requireNameOnly) => false;
public static string GetFriendPersonaName(CSteamID steamId) => string.Empty;
}
public static class SteamUGC
{
public static UGCQueryHandle_t CreateQueryAllUGCRequest(EUGCQuery queryType, EUGCMatchingUGCType matchingType, AppId_t creatorAppId, AppId_t consumerAppId, uint page) => default;
public static UGCQueryHandle_t CreateQueryUserUGCRequest(uint accountId, EUserUGCList listType, EUGCMatchingUGCType matchingType, EUserUGCListSortOrder sortOrder, AppId_t creatorAppId, AppId_t consumerAppId, uint page) => default;
public static bool SetReturnLongDescription(UGCQueryHandle_t handle, bool value) => false;
public static bool SetReturnTotalOnly(UGCQueryHandle_t handle, bool value) => false;
public static SteamAPICall_t SendQueryUGCRequest(UGCQueryHandle_t handle) => default;
public static bool ReleaseQueryUGCRequest(UGCQueryHandle_t handle) => true;
public static bool GetQueryUGCResult(UGCQueryHandle_t handle, uint index, out SteamUGCDetails_t details)
{
details = default;
return false;
}
public static uint GetItemState(PublishedFileId_t fileId) => 0;
public static bool GetItemInstallInfo(PublishedFileId_t fileId, out ulong sizeOnDisk, out string folder, uint folderSize, out uint timestamp)
{
sizeOnDisk = 0;
folder = string.Empty;
timestamp = 0;
return false;
}
public static uint GetNumSubscribedItems() => 0;
public static uint GetSubscribedItems(PublishedFileId_t[] publishedFileIds, uint maxEntries) => 0;
public static SteamAPICall_t SubscribeItem(PublishedFileId_t fileId) => default;
public static SteamAPICall_t UnsubscribeItem(PublishedFileId_t fileId) => default;
public static SteamAPICall_t CreateItem(AppId_t consumerAppId, EWorkshopFileType fileType) => default;
public static UGCUpdateHandle_t StartItemUpdate(AppId_t consumerAppId, PublishedFileId_t fileId) => default;
public static bool SetItemTitle(UGCUpdateHandle_t handle, string title) => false;
public static bool SetItemDescription(UGCUpdateHandle_t handle, string description) => false;
public static bool SetItemContent(UGCUpdateHandle_t handle, string contentFolder) => false;
public static bool SetItemPreview(UGCUpdateHandle_t handle, string previewFile) => false;
public static bool SetItemVisibility(UGCUpdateHandle_t handle, ERemoteStoragePublishedFileVisibility visibility) => false;
public static bool SetItemTags(UGCUpdateHandle_t handle, System.Collections.Generic.IList<string> tags) => false;
public static SteamAPICall_t SubmitItemUpdate(UGCUpdateHandle_t handle, string changeNote) => default;
public static EItemUpdateStatus GetItemUpdateProgress(UGCUpdateHandle_t handle, out ulong bytesProcessed, out ulong bytesTotal)
{
bytesProcessed = 0;
bytesTotal = 0;
return EItemUpdateStatus.k_EItemUpdateStatusInvalid;
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da2c27e88ef14b3d9b65f2b1222f1f5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -2,7 +2,9 @@ using TH1_Core.Events;
using Logic.CrashSight; using Logic.CrashSight;
using TH1_Logic.Config; using TH1_Logic.Config;
using TH1_Logic.Oss; using TH1_Logic.Oss;
#if STEAM_CHANNEL || STEAMWORKS_NET
using Steamworks; using Steamworks;
#endif
using TH1_UI.Controller.Base; using TH1_UI.Controller.Base;
using TH1_UI.View.Global; using TH1_UI.View.Global;
@ -117,6 +119,7 @@ namespace TH1_UI.Controller.Global
private static bool TryGetSteamId(out string steamId) private static bool TryGetSteamId(out string steamId)
{ {
steamId = ""; steamId = "";
#if STEAM_CHANNEL || STEAMWORKS_NET
try try
{ {
if (!SteamUser.BLoggedOn()) if (!SteamUser.BLoggedOn())
@ -134,6 +137,9 @@ namespace TH1_UI.Controller.Global
LogSystem.LogWarning($"PlayerBugReport SteamID unavailable: {ex.Message}"); LogSystem.LogWarning($"PlayerBugReport SteamID unavailable: {ex.Message}");
return false; return false;
} }
#else
return false;
#endif
} }
} }
} }