Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
LoadingScreen.cs
浏览该文件的文档.
1using System.Diagnostics;
2using System.Globalization;
3using System.Reflection;
4using Engine;
6using Engine.Media;
7#if ANDROID
8using Android.App;
9#elif WINDOWS
10//using System.Windows.Forms;
11#endif
12
13namespace Game {
14 public class LoadingScreen : Screen {
21
22 class LogItem(LogType type, string log) {
23 public LogType LogType = type;
24 public string Message = log;
25 }
26
27 List<Action> LoadingActoins = [];
28 List<Action> ModLoadingActoins = [];
29 CanvasWidget Canvas = new() { Size = new Vector2(float.PositiveInfinity) };
30
32 FillColor = SettingsManager.DisplayLog ? Color.Black : Color.White, OutlineThickness = 0f, DepthWriteEnabled = true
33 };
34
36 public static bool m_isContentLoaded;
37 public const string fName = "LoadingScreen";
38
39 static LoadingScreen() {
41 LogList = new ListPanelWidget { Direction = LayoutDirection.Vertical, PlayClickSound = false };
42 LogList.ItemWidgetFactory = obj => {
43 if (obj is LogItem logItem) {
44 CanvasWidget canvasWidget = new() {
46 };
47 FontTextWidget fontTextWidget = new() {
48 FontScale = 0.6f,
49 Text = logItem.Message,
50 Color = GetColor(logItem.LogType),
53 };
54 canvasWidget.Children.Add(fontTextWidget);
55 canvasWidget.IsVisible = true;
56 return canvasWidget;
57 }
58 return null;
59 };
60 LogList.ItemSize = 30;
61 }
62 }
63
64 public static Color GetColor(LogType type) {
65 return type switch {
69 _ => Color.White
70 };
71 }
72
73 public LoadingScreen() {
75 Canvas.AddChildren(Background);
76 Canvas.AddChildren(LogList);
78 }
79 Info($"Initializing Mods Manager. Api Version: {ModsManager.APIVersionString}");
80 }
81
82 public void ContentLoaded() {
84 _ = ContentManager.Get<Image>("Fonts/Pericles", ".webp");
85 m_isContentLoaded = true;
86 return;
87 }
89 RectangleWidget rectangle1 = new() {
90 FillColor = Color.White,
91 OutlineColor = Color.Transparent,
92 Size = new Vector2(256f),
95 };
96 rectangle1.Subtexture = ContentManager.Get<Subtexture>("Textures/Gui/CandyRufusLogo");
97 RectangleWidget rectangle2 = new() {
98 FillColor = Color.White,
99 OutlineColor = Color.Transparent,
100 Size = new Vector2(80f, 50f),
103 Margin = new Vector2(10f)
104 };
105 rectangle2.Subtexture = ContentManager.Get<Subtexture>("Textures/Gui/EngineLogo");
106 BusyBarWidget busyBar = new() {
108 };
109 Canvas.AddChildren(Background);
110 Canvas.AddChildren(rectangle1);
111 Canvas.AddChildren(rectangle2);
112 Canvas.AddChildren(busyBar);
114 m_isContentLoaded = true;
115 Task.Run(() => { _ = ContentManager.Get<Image>("Fonts/Pericles", ".webp"); });
116 }
117
118 //日志已经附带状态,不需要添加状态字符串
119 public static void Error(string mesg) {
120 Add(LogType.Error, mesg);
121 }
122
123 public static void Info(string mesg) {
124 Add(LogType.Info, mesg);
125 }
126
127 public static void Warning(string mesg) {
128 Add(LogType.Warning, mesg);
129 }
130
131 public static void Advice(string mesg) {
132 Add(LogType.Advice, $"[Advice]{mesg}");
133 }
134
135 public static void Add(LogType type, string mesg) {
137 delegate {
138 switch (type) {
139 case LogType.Info:
140 case LogType.Advice: Log.Information(mesg); break;
141 case LogType.Error: Log.Error(mesg); break;
142 case LogType.Warning: Log.Warning(mesg); break;
143 }
145 LogItem item = new(type, mesg);
146 LogList.AddItem(item);
147 LogList.ScrollToItem(item);
148 }
149 }
150 );
151 }
152
153 void InitActions() {
154 bool isLoadSucceed = true;
155 Exception exception = null;
157 delegate { //将所有的有效的scmod读取为ModEntity,并自动添加SurvivalCraftModEntity
160 }
161 );
164 delegate { //检查所有Mod依赖项
165 //根据加载顺序排序后的结果
166 ModsManager.ModList.Clear();
167 foreach (ModEntity item in ModsManager.ModListAll) {
168 if (item.IsDependencyChecked || item.IsDisabled) {
169 continue;
170 }
172 }
173 }
174 );
175 AddLoadAction(() => {
176 Dictionary<string, Assembly[]> assemblies = [];
177 ModsManager.ModListAllDo(modEntity => {
178 bool flag = true;
179 assemblies[modEntity.modInfo.PackageName] = modEntity.GetAssemblies();
180 foreach (Assembly assembly in assemblies[modEntity.modInfo.PackageName]) {
181 if (flag) {
182 Log.Information($"[{modEntity.modInfo.Name}] Getting assemblies.");
183 flag = false;
184 }
185 AssemblyName assemblyName = assembly.GetName();
186 string fullName = assemblyName.FullName;
187 if (ModsManager.Dlls.TryGetValue(fullName, out Assembly existingAssembly)) {
188 if (existingAssembly.GetName().Version < assemblyName.Version) {
189 ModsManager.Dlls[fullName] = assembly;
190 }
191 }
192 else {
193 ModsManager.Dlls.Add(fullName, assembly);
194 }
195 }
196 }
197 );
198 //加载 mod 程序集(.dll)文件
199 //但不进行处理操作(如添加block等)
200 ModsManager.ModListAllDo(modEntity => {
201 if (!isLoadSucceed) {
202 return;
203 }
204 foreach (Assembly asm in assemblies[modEntity.modInfo.PackageName]) {
205 Log.Information($"[{modEntity.modInfo.Name}] Handling assembly [{asm.FullName}]");
206 try {
207 modEntity.HandleAssembly(asm);
208 }
209 catch (Exception e) {
210 exception = e;
211 string separator = new('-', 10); //生成10个 '-' 连一起的字符串
212 Log.Error($"{separator}Handle assembly failed{separator}");
213 Log.Error(
214 $"Loaded assembly:\n{string.Join("\n", AppDomain.CurrentDomain.GetAssemblies().Select(x => x.FullName ?? x.GetName().FullName))}"
215 );
216 Log.Error(separator);
217 Log.Error($"Error assembly: {asm.FullName}");
218#pragma warning disable IL2026
219 Log.Error($"Dependencies:\n{string.Join("\n", asm.GetReferencedAssemblies().Select(x => x.FullName))}");
220#pragma warning restore IL2026
221 Log.Error(separator);
222 Log.Error(e);
223 isLoadSucceed = false;
224 break;
225 }
226 }
227 }
228 );
229 if (!isLoadSucceed) {
230 ModsManager.ModList.RemoveAll(entity => entity is not SurvivalCraftModEntity && entity is not FastDebugModEntity);
231 LoadingActoins.RemoveRange(1, LoadingActoins.Count - 1);
232 ModLoadingActoins.Clear();
235 "Loading failed 加载失败",
236 ["Exceptions: 异常信息:", ..exception?.ToString().Split('\n') ?? []],
237 [
238 $"Check the API version required by mod is equal to the current API version ({ModsManager.APIVersionString}). Check and add missing mods. If not solved, please contact the developer of the mods or API with Game.log in the path below.",
239 $"检查模组是否缺失,并添加所缺失的模组。查看模组所需插件版版本与当前插件版版本({ModsManager.APIVersionString})是否一致。若以上方式都无法解决,请联系模组、插件版开发者,并发送下面路径中的 Game.log",
241 "And you can enable Safe Mode to prevent loading any mod.",
242 "你还可以启用安全模式,防止加载任何模组。"
243 ]
244 )
245 );
246 }
247 //处理程序集
248 }
249 );
251 delegate { //初始化所有ModEntity的语言包
252 //>>>初始化语言列表
254 foreach (ContentInfo contentInfo in ContentManager.List("Lang")) {
255 string fileName = Path.GetFileNameWithoutExtension(contentInfo.Filename);
256 if (string.IsNullOrEmpty(fileName)) {
257 continue;
258 }
259 try {
260#if BROWSER
261 LanguageControl.LanguageTypes.Add(fileName);
262#else
263 CultureInfo cultureInfo = new(fileName.EndsWith("-old") ? fileName.Substring(0, fileName.Length - 4) : fileName, false);
264 LanguageControl.LanguageTypes.TryAdd(fileName, cultureInfo); //第二个参数应为CultureInfo
265#endif
266 }
267 catch (Exception) {
268 // ignore
269 }
270 }
271 //<<<结束
272#if BROWSER
273 if (ModsManager.Configs.TryGetValue("Language", out string value)
274 && LanguageControl.LanguageTypes.Contains(value)) {
276 }
277 else {
278 string systemLanguage = Program.SystemLanguage;
279 if (string.IsNullOrEmpty(systemLanguage)) {
280 //如果不支持系统语言,英语是最佳选择
282 Log.Information("Language is not specified, and system language is not detected, en-US is loaded instead.");
283 }
284 else if (LanguageControl.LanguageTypes.Contains(systemLanguage)) {
285 LanguageControl.Initialize(systemLanguage);
286 Log.Information($"Language is not specified, system language ({systemLanguage}) is successfully loaded.");
287 }
288 else {
289 bool languageNotLoaded = true;
290 string[] systemLanguageArray = systemLanguage.Split('-');
291 switch (systemLanguageArray.Length) {
292 case 1: {
293 foreach (string cultureName in LanguageControl.LanguageTypes) {
294 string[] cultureNameArray = cultureName.Split('-');
295 if (systemLanguage == cultureNameArray[0]) {
296 LanguageControl.Initialize(cultureName);
298 $"Language is not specified, a language ({cultureName}) closest to system language ({systemLanguage}) is successfully loaded."
299 );
300 languageNotLoaded = false;
301 break;
302 }
303 }
304 break;
305 }
306 case >= 2:
307 foreach (string cultureName in LanguageControl.LanguageTypes) {
308 string[] cultureNameArray = cultureName.Split('-');
309 if (systemLanguageArray[0] == cultureNameArray[0]) {
310 LanguageControl.Initialize(cultureName);
312 $"Language is not specified, a language ({cultureName}) closest to system language ({systemLanguage}) is successfully loaded."
313 );
314 languageNotLoaded = false;
315 break;
316 }
317 }
318 break;
319 }
320 if (languageNotLoaded) {
323 $"Language is not specified, and system language ({systemLanguage}) is not supported yet, en-US is loaded instead."
324 );
325 }
326 }
327 }
328#else
329 if (ModsManager.Configs.TryGetValue("Language", out string value)
330 && LanguageControl.LanguageTypes.ContainsKey(value)) {
332 }
333 else {
334 string systemLanguage = Program.SystemLanguage;
335 if (string.IsNullOrEmpty(systemLanguage)) {
336 //如果不支持系统语言,英语是最佳选择
338 Log.Information("Language is not specified, and system language is not detected, en-US is loaded instead.");
339 }
340 else if (LanguageControl.LanguageTypes.ContainsKey(systemLanguage)) {
341 LanguageControl.Initialize(systemLanguage);
342 Log.Information($"Language is not specified, system language ({systemLanguage}) is successfully loaded.");
343 }
344 else {
345 bool languageNotLoaded = true;
346 CultureInfo systemCultureInfoParent = new CultureInfo(systemLanguage).Parent;
347 foreach ((string cultureName, CultureInfo cultureInfo) in LanguageControl.LanguageTypes) {
348 bool similar = false;
349 CultureInfo parentCulture = cultureInfo.Parent;
350 string parentCultureName = cultureInfo.Name;
351 if (parentCultureName == systemLanguage
352 || parentCultureName == systemCultureInfoParent.Name
353 || parentCultureName == systemCultureInfoParent.Parent.Name) {
354 similar = true;
355 }
356 else {
357 string rootCultureName = parentCulture.Parent.Name;
358 if (rootCultureName.Length > 0
359 && (rootCultureName == systemCultureInfoParent.Name
360 || rootCultureName == systemCultureInfoParent.Parent.Name)) {
361 similar = true;
362 }
363 }
364 if (similar) {
365 LanguageControl.Initialize(cultureName);
367 $"Language is not specified, a language ({cultureName}) closest to system language ({systemLanguage}) is successfully loaded."
368 );
369 languageNotLoaded = false;
370 }
371 }
372 if (languageNotLoaded) {
375 $"Language is not specified, and system language ({systemLanguage}) is not supported yet, en-US is loaded instead."
376 );
377 }
378 }
379 }
380#endif
381 ModsManager.ModListAllDo(modEntity => { modEntity.LoadLauguage(); });
383#if !ANDROID
384 string title =
385 $"{(SettingsManager.SafeMode ? $"[{LanguageControl.Get("Usual", "safeMode")}]" : "")}{LanguageControl.Get("Usual", "gameName")} {ModsManager.ShortGameVersion} - {LanguageControl.Get("Usual", "api")} {ModsManager.APIVersionString}";
386#if DEBUG
387 title = $"[{LanguageControl.Get("Usual", "debug")}]{title}";
388#endif
389 Window.TitlePrefix = title;
390#endif
391 }
392 );
393#if !IOS && !BROWSER
395 delegate { //读取所有的ModEntity的JavaScript
397 ModsManager.ModListAllDo(modEntity => { modEntity.LoadJs(); });
399 }
400 );
401#endif
403 delegate {
405 List<Action> actions = [];
407 "OnLoadingStart",
408 loader => {
409 loader.OnLoadingStart(actions);
410 return false;
411 }
412 );
413 foreach (Action ac in actions) {
414 ModLoadingActoins.Add(ac);
415 }
416 }
417 );
420 delegate { //初始化TextureAtlas
423 }
424 );
426 delegate { //初始化Database
427 try {
430 ModsManager.ModListAllDo(modEntity => { modEntity.LoadXdb(ref DatabaseManager.DatabaseNode); });
432 }
433 catch (Exception e) {
434 Warning(e.ToString());
435 }
436 }
437 );
439 delegate {
440 Stopwatch stopwatch = Stopwatch.StartNew();
441 try {
443 }
444 catch (Exception e) {
445 Error(e.ToString());
446 }
447 stopwatch.Stop();
448 Info($"{LanguageControl.Get(fName, "3")}({stopwatch.ElapsedMilliseconds}ms)");
449 }
450 );
452 delegate { //初始化方块管理器
453 Stopwatch stopwatch = Stopwatch.StartNew();
455 stopwatch.Stop();
456 Info($"{LanguageControl.Get(fName, "4")}({stopwatch.ElapsedMilliseconds}ms)");
457 }
458 );
459 AddLoadAction(CraftingRecipesManager.Initialize); //初始化合成谱
461 delegate {
471 }
472 );
474 delegate {
477 }
478 );
479 InitScreens();
482 delegate {
483 ModsManager.ModListAllDo(modEntity => {
484 if (modEntity.Loader != null) {
485 Info($"[{modEntity.modInfo?.Name}] {LanguageControl.Get(fName, "6")}");
486 modEntity.Loader.OnLoadingFinished(ModLoadingActoins);
487 }
488 }
489 );
490 }
491 );
492 AddLoadAction(KeyCompatibleGroupsManager.Initialize); //初始化按键兼容组
493 AddLoadAction(delegate { ScreensManager.SwitchScreen("MainMenu"); });
494 }
495
496 void InitScreens() {
497 AddLoadAction(delegate { AddScreen("Nag", new NagScreen()); });
498 AddLoadAction(delegate { AddScreen("MainMenu", new MainMenuScreen()); });
499 AddLoadAction(delegate { AddScreen("Recipaedia", new RecipaediaScreen()); });
500 AddLoadAction(delegate { AddScreen("Bestiary", new BestiaryScreen()); });
501 AddLoadAction(delegate { AddScreen("BestiaryDescription", new BestiaryDescriptionScreen()); });
502 AddLoadAction(delegate { AddScreen("Help", new HelpScreen()); });
503 AddLoadAction(delegate { AddScreen("HelpTopic", new HelpTopicScreen()); });
504 AddLoadAction(delegate { AddScreen("Settings", new SettingsScreen()); });
505 AddLoadAction(delegate { AddScreen("SettingsPerformance", new SettingsPerformanceScreen()); });
506 AddLoadAction(delegate { AddScreen("SettingsGraphics", new SettingsGraphicsScreen()); });
507 AddLoadAction(delegate { AddScreen("SettingsUi", new SettingsUiScreen()); });
508 AddLoadAction(delegate { AddScreen("SettingsCompatibility", new SettingsCompatibilityScreen()); });
509 AddLoadAction(delegate { AddScreen("SettingsAudio", new SettingsAudioScreen()); });
510 AddLoadAction(delegate { AddScreen("SettingsControls", new SettingsControlsScreen()); });
511 AddLoadAction(delegate { AddScreen("Play", new PlayScreen()); });
512 AddLoadAction(delegate { AddScreen("NewWorld", new NewWorldScreen()); });
513 AddLoadAction(delegate { AddScreen("ModifyWorld", new ModifyWorldScreen()); });
514 AddLoadAction(delegate { AddScreen("WorldOptions", new WorldOptionsScreen()); });
515 AddLoadAction(delegate { AddScreen("GameLoading", new GameLoadingScreen()); });
516 AddLoadAction(delegate { AddScreen("Game", new GameScreen()); });
517 AddLoadAction(delegate { AddScreen("TrialEnded", new TrialEndedScreen()); });
518 AddLoadAction(delegate { AddScreen("ExternalContent", new ExternalContentScreen()); });
519 AddLoadAction(delegate { AddScreen("CommunityContent", new CommunityContentScreen()); });
520 AddLoadAction(delegate { AddScreen("OriginalCommunityContent", new OriginalCommunityContentScreen()); });
521 AddLoadAction(delegate { AddScreen("Content", new ContentScreen()); });
522 AddLoadAction(delegate { AddScreen("ManageContent", new ManageContentScreen()); });
523 AddLoadAction(delegate { AddScreen("ModsManageContent", new ModsManageContentScreen()); });
524 AddLoadAction(delegate { AddScreen("Releases", new ReleasesScreen()); });
525 /*AddLoadAction(delegate
526 {
527 AddScreen("ManageUser", new ManageUserScreen());
528 });*/
529 AddLoadAction(delegate { AddScreen("Players", new PlayersScreen()); });
530 AddLoadAction(delegate { AddScreen("Player", new PlayerScreen()); });
531 AddLoadAction(delegate { AddScreen("KeyboardMapping", new KeyboardMappingScreen()); });
532 AddLoadAction(delegate { AddScreen("GamepadMapping", new GamepadMappingScreen()); });
533 AddLoadAction(delegate { AddScreen("CameraManage", new CameraManageScreen()); });
534 AddLoadAction(delegate { AddScreen("ManageClassSubstitutes", new ManageClassSubstitutesScreen()); });
535 }
536
537 public void AddScreen(string name, Screen screen) {
538 ScreensManager.AddScreen(name, screen);
539 }
540
541 void AddLoadAction(Action action) {
542 LoadingActoins.Add(action);
543 }
544
545 public override void Leave() {
546 LogList?.ClearItems();
547#if ANDROID
548 // 当前Android端SDL不支持半垂直同步
551 }
552#endif
554 ContentManager.Dispose("Textures/Gui/CandyRufusLogo");
555 ContentManager.Dispose("Textures/Gui/EngineLogo");
556 }
557
558 public override void Enter(object[] parameters) {
560 List<string> remove = new();
561 foreach (KeyValuePair<string, Screen> screen in ScreensManager.m_screens) {
562 if (screen.Value == this) {
563 continue;
564 }
565 remove.Add(screen.Key);
566 }
567 foreach (string screen in remove) {
568 ScreensManager.m_screens.Remove(screen);
569 }
570 InitActions();
571 base.Enter(parameters);
572 }
573
574 public override void Update() {
575 if (Input.Back
576 || Input.Cancel) {
577 ConfirmQuit();
578 }
580 return;
581 }
582 Stopwatch sw = Stopwatch.StartNew();
583 while (!m_isContentLoaded
584 || sw.ElapsedMilliseconds < 100) {
585 if (ModLoadingActoins.Count > 0) {
586 try {
587 ModLoadingActoins[0].Invoke();
588 }
589 catch (Exception e) {
590 Error(e.ToString());
591 break;
592 }
593 finally {
594 ModLoadingActoins.RemoveAt(0);
595 }
596 }
597 else if (LoadingActoins.Count > 0) {
598 try {
599 LoadingActoins[0].Invoke();
600 }
601 catch (Exception e) {
602 Error(e.ToString());
603 break;
604 }
605 finally {
606 LoadingActoins.RemoveAt(0);
607 }
608 }
609 else {
610 break;
611 }
612 }
613 sw.Stop();
614 }
615
616 public void ConfirmQuit() {
617#if ANDROID
618#pragma warning disable CA1416
619 if (Android.OS.Build.VERSION.SdkInt < (Android.OS.BuildVersionCodes)21) {
620 Window.Close();
621 return;
622 }
623 Window.Activity.RunOnUiThread(() => {
624 new AlertDialog.Builder(Window.Activity).SetMessage("Exit 退出?")
625 ?.SetPositiveButton("Yes 是", (_, _) => { Window.Close(); })
626 ?.SetNegativeButton("No 否", (_, _) => { })
627 ?.Show();
628 }
629 );
630#pragma warning restore CA1416
631#elif WINDOWS
632 /*
633 Task.Run(() =>
634 {
635 if(MessageBox.Show("Exit 退出?","", MessageBoxButtons.YesNo) == DialogResult.Yes)
636 {
637 Window.Close();
638 }
639 });*/
640#endif
641 }
642 }
643}
static void Dispatch(Action action, bool waitUntilCompleted=false)
static Viewport Viewport
static void Error(object message)
定义 Log.cs:80
static void Information(object message)
定义 Log.cs:56
static void Warning(object message)
定义 Log.cs:68
static string GetSystemPath(string path)
static string TitlePrefix
static void Close()
static int PresentationInterval
static void Initialize()
readonly WidgetsList Children
void AddChildren(Widget widget)
static object Get(Type type, string name)
static ReadOnlyList< ContentInfo > List()
static void Dispose(string name)
可能需要带上文件后缀,即获取名字+获取的后缀
static void LoadDataBaseFromXml(XElement node)
static void RegisterEvent()
static void Initiate()
static void Initialize(string languageType)
static Dictionary< string, CultureInfo > LanguageTypes
语言标识符、与相应的CultureInfo
static void SetUsual(bool force=false)
static string Get(string className, int key)
获取在当前语言类名键对应的字符串
void AddLoadAction(Action action)
List< Action > ModLoadingActoins
override void Enter(object[] parameters)
static void Advice(string mesg)
static void Info(string mesg)
static ListPanelWidget LogList
void AddScreen(string name, Screen screen)
static void Error(string mesg)
static void Warning(string mesg)
RectangleWidget Background
static Color GetColor(LogType type)
static void Add(LogType type, string mesg)
List< Action > LoadingActoins
virtual void CheckDependencies(List< ModEntity > modEntities=null)
检查依赖项
static void Initialize()
static string SystemLanguage
static void SwitchScreen(string name, params object[] parameters)
static void AddScreen(string name, Screen screen)
static Dictionary< string, Screen > m_screens
virtual WidgetAlignment VerticalAlignment
virtual Vector2 Margin
virtual WidgetAlignment HorizontalAlignment
void Add(Widget widget)
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static string LogPath
static List< ModEntity > ModList
所有已启用的模组
static bool GetAllowContinue()
static Dictionary< string, string > Configs
static Dictionary< string, Assembly > Dlls
static void ModListAllDo(Action< ModEntity > entity)
static void DealWithClassSubstitutes()
static void Initialize()
static List< ModEntity > ModListAll
所有模组,含禁用的
static void InitImportantDatabaseClasses()
static Color Cyan
static Color Transparent
定义 Color.cs:5
static Color Red
static Color White
static Color Yellow