初始化

This commit is contained in:
come
2025-07-26 16:56:42 +08:00
parent 8291dbb91c
commit fa81439a8c
2574 changed files with 328492 additions and 2170 deletions

View File

@@ -16,12 +16,7 @@ MonoBehaviour:
m_Data:
m_SerializedData: []
m_GUID: 225bd79756fccf14b86d3deb4a2750b7
m_SerializeEntries:
- m_GUID: df19a62afc91680458a47c27783266c1
m_Address: Prefabs/UI/MainView
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
m_SerializeEntries: []
m_ReadOnly: 0
m_Settings: {fileID: 11400000, guid: bee6bc9b5cc8353408a831cc694fcc59, type: 2}
m_SchemaSet:

View File

@@ -1,169 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2144746790689463245
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4433487652878264011}
- component: {fileID: 4598575638834120631}
- component: {fileID: 979075320078913737}
m_Layer: 5
m_Name: Text (Legacy)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4433487652878264011
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2144746790689463245}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 180925369222541037}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4598575638834120631
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2144746790689463245}
m_CullTransparentMesh: 1
--- !u!114 &979075320078913737
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2144746790689463245}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 30
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 3
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: New Text
--- !u!1 &3291374494798134796
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 180925369222541037}
- component: {fileID: 8800204140203976600}
- component: {fileID: 7345399528756125477}
- component: {fileID: 6862961716912536255}
m_Layer: 5
m_Name: Item
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &180925369222541037
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3291374494798134796}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4433487652878264011}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 100, y: -360}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &8800204140203976600
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3291374494798134796}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: 200
m_PreferredHeight: 50
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &7345399528756125477
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3291374494798134796}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d7f07a01cdb5c7c4aa72a3a420035842, type: 3}
m_Name:
m_EditorClassIdentifier:
entries:
- key: MainItem
prefab: {fileID: 2144746790689463245}
selectedComponentName: Text
--- !u!114 &6862961716912536255
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3291374494798134796}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 391eb6d877254380bf561b14e4be836f, type: 3}
m_Name:
m_EditorClassIdentifier:
text: {fileID: 979075320078913737}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b3ddfe80d5274d25869bbd0ad6bae9f9
timeCreated: 1752637115

View File

@@ -1,154 +0,0 @@
using System.Linq;
using UnityEditor;
using UnityEngine;
using CreatGame.UI;
using UnityEditorInternal;
using Unity.VisualScripting;
using System.Collections.Generic;
[CustomEditor(typeof(UIComponentExport))]
public class UIComponentExportEditor : Editor
{
private ReorderableList reorderableList;
private void InitReorderableList()
{
reorderableList = new ReorderableList(
serializedObject,
serializedObject.FindProperty("entries"),
true, true, true, true);
reorderableList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "UI Prefab Entries"); };
reorderableList.elementHeightCallback = (int index) => { return EditorGUIUtility.singleLineHeight + 6f; };
reorderableList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(index);
// drawElementCallback 中的内容
SerializedProperty keyProp = element.FindPropertyRelative("key");
SerializedProperty prefabProp = element.FindPropertyRelative("prefab");
SerializedProperty selectedNameProp = element.FindPropertyRelative("selectedComponentName");
GameObject prefab = prefabProp.objectReferenceValue as GameObject;
// 查找组件类型
List<string> uguiComponentNames = new List<string>();
if (prefab != null)
{
uguiComponentNames = prefab.GetComponents<Component>()
.Where(c => c != null && UIViewExportEditor.IsUGUIComponent(c))
.Select(c => c.GetType().Name)
.Distinct()
.ToList();
if (prefab.GetComponent<UISelectList>() != null)
{
uguiComponentNames.Add("UISelectList");
}
if (uguiComponentNames.Count == 0)
{
uguiComponentNames.Add("GameObject");
}
}
float lineHeight = EditorGUIUtility.singleLineHeight;
float padding = 4f;
float thirdWidth = (rect.width - 2 * padding) / 3f;
Rect keyRect = new Rect(rect.x, rect.y + 2, thirdWidth, lineHeight);
Rect prefabRect = new Rect(rect.x + thirdWidth + padding, rect.y + 2, thirdWidth, lineHeight);
Rect popupRect = new Rect(rect.x + 2 * (thirdWidth + padding), rect.y + 2, thirdWidth, lineHeight);
// key 字段
EditorGUI.PropertyField(keyRect, keyProp, GUIContent.none);
// prefab 字段
EditorGUI.PropertyField(prefabRect, prefabProp, GUIContent.none);
// 下拉框
if (uguiComponentNames.Count > 0)
{
int selectedIndex = Mathf.Max(0, uguiComponentNames.IndexOf(selectedNameProp.stringValue));
selectedIndex = EditorGUI.Popup(popupRect, selectedIndex, uguiComponentNames.ToArray());
selectedNameProp.stringValue = uguiComponentNames[selectedIndex];
}
else
{
EditorGUI.LabelField(popupRect, "无UGUI组件");
}
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
if (reorderableList == null)
{
InitReorderableList();
}
reorderableList?.DoLayoutList();
serializedObject.ApplyModifiedProperties();
if (GUILayout.Button("导出代码"))
{
ExportCode();
}
}
/// <summary>
/// 导出代码
/// </summary>
private void ExportCode()
{
string savePath = Application.dataPath + "/Scripts/GameLogic/Export/UGUI/";
if (string.IsNullOrEmpty(savePath))
return;
string className = $"UI{target.GameObject().name}";
string filename = System.IO.Path.Combine(savePath, $"{className}.cs");
var sb = new System.Text.StringBuilder();
sb.AppendLine("using UnityEngine;");
sb.AppendLine("using UnityEngine.UI;");
sb.AppendLine();
sb.AppendLine("namespace CreatGame.UI");
sb.AppendLine("{");
sb.AppendLine($" public partial class {className} : UIComponentBase");
sb.AppendLine(" {");
// sb.AppendLine($" public override string PrefabPath => \"Prefabs/UI/{target.GameObject().name}\";");
// 字段定义
for (int i = 0; i < reorderableList.count; i++)
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i);
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// ");
sb.AppendLine(" /// </summary>");
sb.AppendLine($" public {element.FindPropertyRelative("selectedComponentName").stringValue} {element.FindPropertyRelative("key").stringValue};");
}
sb.AppendLine(" public override void PreLoad(GameObject view)");
sb.AppendLine(" {");
sb.AppendLine(" base.PreLoad(view);");
sb.AppendLine();
for (int i = 0; i < reorderableList.count; i++)
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i);
var filedName = element.FindPropertyRelative("key").stringValue;
var typeName = element.FindPropertyRelative("selectedComponentName").stringValue;
sb.AppendLine($" {filedName} = m_ViewExport.GetGameObject(nameof({filedName})).GetComponent<{typeName}>();");
}
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine("}");
Debug.Log(sb.ToString());
System.IO.File.WriteAllText(filename, sb.ToString());
Debug.Log($"✅ 导出成功:{filename}");
AssetDatabase.Refresh();
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 75e425207f8b4c369bf1a58bd14d8cb4
timeCreated: 1752945208

View File

@@ -1,181 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using CreatGame.UI;
using Unity.VisualScripting;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.UI;
[CustomEditor(typeof(UIViewExport))]
public class UIViewExportEditor : Editor
{
private ReorderableList reorderableList;
private void OnEnable()
{
}
private void InitReorderableList()
{
reorderableList = new ReorderableList(
serializedObject,
serializedObject.FindProperty("entries"),
true, true, true, true);
reorderableList.drawHeaderCallback = (Rect rect) =>
{
EditorGUI.LabelField(rect, "UI Prefab Entries");
};
reorderableList.elementHeightCallback = (int index) =>
{
return EditorGUIUtility.singleLineHeight + 6f;
};
reorderableList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(index);
// drawElementCallback 中的内容
SerializedProperty keyProp = element.FindPropertyRelative("key");
SerializedProperty prefabProp = element.FindPropertyRelative("prefab");
SerializedProperty selectedNameProp = element.FindPropertyRelative("selectedComponentName");
GameObject prefab = prefabProp.objectReferenceValue as GameObject;
// 查找组件类型
List<string> uguiComponentNames = new List<string>();
if (prefab != null)
{
uguiComponentNames = prefab.GetComponents<Component>()
.Where(c => c != null && IsUGUIComponent(c))
.Select(c => c.GetType().Name)
.Distinct()
.ToList();
if (prefab.GetComponent<UISelectList>() != null)
{
uguiComponentNames.Add("UISelectList");
}
if (uguiComponentNames.Count == 0)
{
uguiComponentNames.Add("GameObject");
}
}
float lineHeight = EditorGUIUtility.singleLineHeight;
float padding = 4f;
float thirdWidth = (rect.width - 2 * padding) / 3f;
Rect keyRect = new Rect(rect.x, rect.y + 2, thirdWidth, lineHeight);
Rect prefabRect = new Rect(rect.x + thirdWidth + padding, rect.y + 2, thirdWidth, lineHeight);
Rect popupRect = new Rect(rect.x + 2 * (thirdWidth + padding), rect.y + 2, thirdWidth, lineHeight);
// key 字段
EditorGUI.PropertyField(keyRect, keyProp, GUIContent.none);
// prefab 字段
EditorGUI.PropertyField(prefabRect, prefabProp, GUIContent.none);
// 下拉框
if (uguiComponentNames.Count > 0)
{
int selectedIndex = Mathf.Max(0, uguiComponentNames.IndexOf(selectedNameProp.stringValue));
selectedIndex = EditorGUI.Popup(popupRect, selectedIndex, uguiComponentNames.ToArray());
selectedNameProp.stringValue = uguiComponentNames[selectedIndex];
}
else
{
EditorGUI.LabelField(popupRect, "无UGUI组件");
}
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
if (reorderableList == null)
{
InitReorderableList();
}
reorderableList?.DoLayoutList();
serializedObject.ApplyModifiedProperties();
if (GUILayout.Button("导出代码"))
{
ExportCode();
}
}
/// <summary>
/// 判断是否是常见UGUI组件你可以自行扩展
/// </summary>
public static bool IsUGUIComponent(Component component)
{
return component is Graphic // 基类,包含 Image、Text、RawImage
|| component is Button
|| component is Toggle
|| component is Slider
|| component is ScrollRect
|| component is Dropdown
|| component is InputField
|| component is UILoopList;
}
/// <summary>
/// 导出代码
/// </summary>
private void ExportCode()
{
string savePath = Application.dataPath + "/Scripts/GameLogic/Export/UGUI/";
if (string.IsNullOrEmpty(savePath))
return;
string className = $"UI{target.GameObject().name}";
string filename = System.IO.Path.Combine(savePath, $"{className}.cs");
var sb = new System.Text.StringBuilder();
sb.AppendLine("using UnityEngine;");
sb.AppendLine("using UnityEngine.UI;");
sb.AppendLine();
sb.AppendLine("namespace CreatGame.UI");
sb.AppendLine("{");
sb.AppendLine($" public partial class {className} : UIViewBase");
sb.AppendLine(" {");
sb.AppendLine($" public override string PrefabPath => \"Prefabs/UI/{target.GameObject().name}\";");
// 字段定义
for (int i = 0; i < reorderableList.count; i++)
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i);
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// ");
sb.AppendLine(" /// </summary>");
sb.AppendLine($" public {element.FindPropertyRelative("selectedComponentName").stringValue} {element.FindPropertyRelative("key").stringValue};");
}
sb.AppendLine(" public override void PreLoad(GameObject view)");
sb.AppendLine(" {");
sb.AppendLine(" base.PreLoad(view);");
sb.AppendLine();
for (int i = 0; i < reorderableList.count; i++)
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i);
var filedName = element.FindPropertyRelative("key").stringValue;
var typeName = element.FindPropertyRelative("selectedComponentName").stringValue;
sb.AppendLine($" {filedName} = m_ViewExport.GetGameObject(nameof({filedName})).GetComponent<{typeName}>();");
}
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine("}");
Debug.Log(sb.ToString());
System.IO.File.WriteAllText(filename, sb.ToString());
Debug.Log($"✅ 导出成功:{filename}");
AssetDatabase.Refresh();
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7580782f3f2c4729bb6f9c136708540c
timeCreated: 1752637136

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 18f78eb5a545e4646b10c56aee55a6d1
guid: 2b32b7b6f992de44fbd9f12565e6176d
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2f0b0c553be8edd4682e9180fdd13e37, type: 3}
m_Name: I2Languages
m_EditorClassIdentifier:
mSource:
UserAgreesToHaveItOnTheScene: 0
UserAgreesToHaveItInsideThePluginsFolder: 0
GoogleLiveSyncIsUptoDate: 1
mTerms: []
CaseInsensitiveTerms: 0
OnMissingTranslation: 1
mTerm_AppName:
mLanguages: []
IgnoreDeviceLanguage: 0
_AllowUnloadingLanguages: 0
Google_WebServiceURL:
Google_SpreadsheetKey:
Google_SpreadsheetName:
Google_LastUpdatedVersion:
Google_Password: change_this
GoogleUpdateFrequency: 3
GoogleInEditorCheckFrequency: 2
GoogleUpdateSynchronization: 1
GoogleUpdateDelay: 0
Assets: []
Spreadsheet_LocalFileName:
Spreadsheet_LocalCSVSeparator: ','
Spreadsheet_LocalCSVEncoding: utf-8
Spreadsheet_SpecializationAsRows: 1

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cac0d3bc373cde948b3f5412ed44a32d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1d0d11aa1ccf46747a01fc3653b60194
guid: 04e56158d4d3eee498b8726b20cc9172
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b32bd69d879747c8bdf5a3e8c313560c
timeCreated: 1752544984

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7ae98d1b6ba74880a5bdbd3cefd09faa
timeCreated: 1752544970

View File

@@ -1,59 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace cfg
{
public sealed partial class Language : Luban.BeanBase
{
public Language(ByteBuf _buf)
{
Id = _buf.ReadString();
CN = _buf.ReadString();
EN = _buf.ReadString();
}
public static Language DeserializeLanguage(ByteBuf _buf)
{
return new Language(_buf);
}
/// <summary>
/// id
/// </summary>
public readonly string Id;
/// <summary>
/// 中文
/// </summary>
public readonly string CN;
/// <summary>
/// 英文
/// </summary>
public readonly string EN;
public const int __ID__ = -1548945544;
public override int GetTypeId() => __ID__;
public void ResolveRef(Tables tables)
{
}
public override string ToString()
{
return "{ "
+ "id:" + Id + ","
+ "CN:" + CN + ","
+ "EN:" + EN + ","
+ "}";
}
}
}

View File

@@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace cfg
{
public partial class Tables
{
public TbLanguage TbLanguage {get; }
public Tables(System.Func<string, ByteBuf> loader)
{
TbLanguage = new TbLanguage(loader("tblanguage"));
ResolveRef();
}
private void ResolveRef()
{
TbLanguage.ResolveRef(this);
}
}
}

View File

@@ -1,52 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace cfg
{
public partial class TbLanguage
{
private readonly System.Collections.Generic.Dictionary<string, Language> _dataMap;
private readonly System.Collections.Generic.List<Language> _dataList;
public TbLanguage(ByteBuf _buf)
{
_dataMap = new System.Collections.Generic.Dictionary<string, Language>();
_dataList = new System.Collections.Generic.List<Language>();
for(int n = _buf.ReadSize() ; n > 0 ; --n)
{
Language _v;
_v = global::cfg.Language.DeserializeLanguage(_buf);
_dataList.Add(_v);
_dataMap.Add(_v.Id, _v);
}
}
public System.Collections.Generic.Dictionary<string, Language> DataMap => _dataMap;
public System.Collections.Generic.List<Language> DataList => _dataList;
public Language GetOrDefault(string key) => _dataMap.TryGetValue(key, out var v) ? v : null;
public Language Get(string key) => _dataMap[key];
public Language this[string key] => _dataMap[key];
public void ResolveRef(Tables tables)
{
foreach(var _v in _dataList)
{
_v.ResolveRef(tables);
}
}
}
}

View File

@@ -1,45 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace cfg
{
public partial struct vector2
{
public vector2(ByteBuf _buf)
{
X = _buf.ReadFloat();
Y = _buf.ReadFloat();
}
public static vector2 Deserializevector2(ByteBuf _buf)
{
return new vector2(_buf);
}
public readonly float X;
public readonly float Y;
public void ResolveRef(Tables tables)
{
}
public override string ToString()
{
return "{ "
+ "x:" + X + ","
+ "y:" + Y + ","
+ "}";
}
}
}

View File

@@ -1,48 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace cfg
{
public partial struct vector3
{
public vector3(ByteBuf _buf)
{
X = _buf.ReadFloat();
Y = _buf.ReadFloat();
Z = _buf.ReadFloat();
}
public static vector3 Deserializevector3(ByteBuf _buf)
{
return new vector3(_buf);
}
public readonly float X;
public readonly float Y;
public readonly float Z;
public void ResolveRef(Tables tables)
{
}
public override string ToString()
{
return "{ "
+ "x:" + X + ","
+ "y:" + Y + ","
+ "z:" + Z + ","
+ "}";
}
}
}

View File

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

View File

@@ -1,51 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace cfg
{
public partial struct vector4
{
public vector4(ByteBuf _buf)
{
X = _buf.ReadFloat();
Y = _buf.ReadFloat();
Z = _buf.ReadFloat();
W = _buf.ReadFloat();
}
public static vector4 Deserializevector4(ByteBuf _buf)
{
return new vector4(_buf);
}
public readonly float X;
public readonly float Y;
public readonly float Z;
public readonly float W;
public void ResolveRef(Tables tables)
{
}
public override string ToString()
{
return "{ "
+ "x:" + X + ","
+ "y:" + Y + ","
+ "z:" + Z + ","
+ "w:" + W + ","
+ "}";
}
}
}

View File

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

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 48f786d98d3d1d24296e6825756cf55a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,25 +0,0 @@
using UnityEngine;
using UnityEngine.UI;
namespace CreatGame.UI
{
public partial class UIMainView : UIViewBase
{
public override string PrefabPath => "Prefabs/UI/MainView";
/// <summary>
///
/// </summary>
public Button StarBtn;
/// <summary>
///
/// </summary>
public Text StarBtnText;
public override void PreLoad(GameObject view)
{
base.PreLoad(view);
StarBtn = GetGameObject(nameof(StarBtn)).GetComponent<Button>();
StarBtnText = GetGameObject(nameof(StarBtnText)).GetComponent<Text>();
}
}
}

View File

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

View File

@@ -1,31 +0,0 @@
using System.Collections;
using CreatGame.UI;
using UnityEditor.VersionControl;
namespace CreatGame
{
public class GameLogic : Singleton<GameLogic>
{
public IEnumerator Start()
{
AssetBundle.AssetBundleManager.Instance.Initialize();
while (true)
{
if (AssetBundle.AssetBundleManager.Instance.IsInitializeAsync)
{
break;
}
yield return null;
}
UIManager.Instance.OpenView<UI.UIMainView>(UILayer.Main);
}
public void Destroy()
{
AssetBundle.AssetBundleManager.Instance.ReleaseAll();
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8bed5572501d4f149c84589085bec321
timeCreated: 1752463362

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 341fa7946cf046c1ae980f1f3efabbda
timeCreated: 1752547061

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 12e2e1bf012c4e74951a89b77d46f08c
timeCreated: 1752547082

View File

@@ -1,101 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
public class AddressableUpdater : MonoBehaviour
{
public string remoteCatalogUrl; // CDN catalog 路径
public Action<float> OnProgressChanged; // 进度更新回调 0~1
public Action<float> OnSpeedChanged; // 下载速度更新 (KB/s)
public Action<float> OnDownloadSizeFetched; // 总下载大小回调 (MB)
public Action OnCompleted; // 下载完成
private float lastDownloadedBytes = 0;
private float updateCheckInterval = 0.5f;
void Start()
{
StartCoroutine(UpdateAddressables());
}
IEnumerator UpdateAddressables()
{
// 1. 初始化 Addressables
var initHandle = Addressables.InitializeAsync();
yield return initHandle;
// 2. 更新 Catalog
var catalogHandle = Addressables.UpdateCatalogs();
yield return catalogHandle;
List<IResourceLocator> catalogs = catalogHandle.Result;
// 3. 获取资源下载大小
var sizeHandle = Addressables.GetDownloadSizeAsync(Addressables.ResourceManager.ResourceProviders);
yield return sizeHandle;
long totalDownloadSize = sizeHandle.Result;
if (totalDownloadSize <= 0)
{
Debug.Log("无需更新");
OnCompleted?.Invoke();
yield break;
}
OnDownloadSizeFetched?.Invoke(totalDownloadSize / (1024f * 1024f)); // MB
// 4. 开始下载所有资源
var downloadHandle = Addressables.DownloadDependenciesAsync(Addressables.ResourceManager.ResourceProviders, true);
StartCoroutine(TrackDownloadProgress(downloadHandle, totalDownloadSize));
yield return downloadHandle;
if (downloadHandle.Status == AsyncOperationStatus.Succeeded)
{
Debug.Log("热更完成!");
OnCompleted?.Invoke();
}
else
{
Debug.LogError("热更失败!");
}
}
IEnumerator TrackDownloadProgress(AsyncOperationHandle handle, long totalSize)
{
float lastTime = Time.realtimeSinceStartup;
float lastDownloaded = 0;
while (!handle.IsDone)
{
float percent = handle.PercentComplete;
OnProgressChanged?.Invoke(percent);
float currentTime = Time.realtimeSinceStartup;
float elapsed = currentTime - lastTime;
if (elapsed >= updateCheckInterval)
{
float currentDownloaded = percent * totalSize;
float speed = (currentDownloaded - lastDownloaded) / elapsed / 1024f; // KB/s
OnSpeedChanged?.Invoke(speed);
lastTime = currentTime;
lastDownloaded = currentDownloaded;
}
yield return null;
}
OnProgressChanged?.Invoke(1f);
OnSpeedChanged?.Invoke(0);
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 2bbf6478f2ed4dd0ac123f2a03fe3695
timeCreated: 1752549280

View File

@@ -1,209 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.U2D;
namespace CreatGame.AssetBundle
{
public class AssetBundleManager : Singleton<AssetBundleManager>
{
private class AssetBundleData
{
public string assetBundleName;
public GameObject assetBundle;
}
/// <summary>
///
/// </summary>
private Dictionary<string, AssetBundleData> m_AssetBundles;
/// <summary>
///
/// </summary>
private Dictionary<string, SpriteAtlas> m_SpriteAtlasCache;
/// <summary>
/// 是否初始化完成
/// </summary>
public bool IsInitializeAsync;
/// <summary>
/// 需要初始化Addressble系统
/// </summary>
public AssetBundleManager()
{
IsInitializeAsync = false;
m_AssetBundles = new Dictionary<string, AssetBundleData>();
m_SpriteAtlasCache = new Dictionary<string, SpriteAtlas>();
Addressables.InitializeAsync();
}
public void Initialize()
{
Addressables.InitializeAsync().Completed += OnInitializeCompleted;
}
/// <summary>
/// 初始化信息回调
/// </summary>
private void OnInitializeCompleted(AsyncOperationHandle<IResourceLocator> operationHandle)
{
if (operationHandle.Status == AsyncOperationStatus.Succeeded)
{
Debug.Log("Addressables initialization succeeded");
#region MyRegion
// IResourceLocator locator = operationHandle.Result;
// foreach (object locatorKey in locator.Keys)
// {
// locator.Locate(locatorKey,typeof(UnityEngine.Object),out IList<IResourceLocation> locations);
// if (locations == null)
// {
// continue;
// }
//
// foreach (var location in locations)
// {
// string key = location.PrimaryKey;
// Addressables.LoadAssetAsync<UnityEngine.Object>(key).Completed += (handle) =>
// {
// if (handle.Status == AsyncOperationStatus.Succeeded)
// {
// Debug.Log("Addressables load asset succeeded");
// var asset = handle.Result;
// GameObject.Instantiate(asset);
// }
// };
// }
// }
#endregion
IsInitializeAsync = true;
}
}
/// <summary>
/// 异步加载资源
/// </summary>
/// <param name="assetBundleName"></param>
/// <param name="callback"></param>
public void LoadGameObjectAsync(string assetBundleName, Action<GameObject> callback)
{
if (m_AssetBundles.TryGetValue(assetBundleName, out var bundle))
{
callback.Invoke(GameObject.Instantiate(bundle.assetBundle));
return;
}
Addressables.LoadAssetAsync<GameObject>(assetBundleName).Completed += (handle) =>
{
if (handle.Status == AsyncOperationStatus.Succeeded)
{
var assetData = CacheAssetBundles(assetBundleName, handle.Result);
Addressables.Release(handle);
callback?.Invoke(GameObject.Instantiate(assetData.assetBundle));
}
else
{
Debug.Log($"assetBundleName = {assetBundleName} 加载失败 Status = {handle.Status}");
callback?.Invoke(null);
}
};
}
/// <summary>
/// 同步等待加载资源
/// </summary>
/// <param name="assetBundleName"></param>
public GameObject LoadGameObject(string assetBundleName)
{
if (m_AssetBundles.TryGetValue(assetBundleName, out var bundle))
{
return GameObject.Instantiate(bundle.assetBundle);
}
var handle = Addressables.LoadAssetAsync<GameObject>(assetBundleName);
handle.WaitForCompletion();
if (handle.Status == AsyncOperationStatus.Succeeded)
{
bundle = CacheAssetBundles(assetBundleName, handle.Result);
Addressables.Release(handle);
return GameObject.Instantiate(bundle.assetBundle);
}
Debug.LogError("资源加载失败");
return null;
}
/// <summary>
/// 缓存加载出来的资源
/// </summary>
/// <param name="bundleName"></param>
/// <param name="bundle"></param>
/// <returns></returns>
private AssetBundleData CacheAssetBundles(string bundleName, GameObject bundle = null)
{
var data = new AssetBundleData(){assetBundleName = bundleName, assetBundle = bundle};
m_AssetBundles.Add(bundleName, data);
return data;
}
/// <summary>
/// 同步加载图集
/// </summary>
/// <param name="atlasName"></param>
/// <returns></returns>
public SpriteAtlas LoadSpriteAtlas(string atlasName)
{
if (m_SpriteAtlasCache.TryGetValue(atlasName, out var atlas))
{
return atlas;
}
var handle = Addressables.LoadAssetAsync<SpriteAtlas>(atlasName);
handle.WaitForCompletion();
if (handle.Status == AsyncOperationStatus.Succeeded)
{
atlas = handle.Result;
Addressables.Release(handle);
m_SpriteAtlasCache.Add(atlasName, atlas);
return atlas;
}
Debug.LogError($"图集加载失败 atlasName = {atlasName} Status = {handle.Status}");
return null;
}
/// <summary>
/// 异步加载图集
/// </summary>
/// <param name="assetBundleName"></param>
/// <param name="callback"></param>
public void LoadSpriteAsync(string atlasName, Action<SpriteAtlas> callback)
{
if (m_SpriteAtlasCache.TryGetValue(atlasName, out var atlas))
{
callback.Invoke(atlas);
return;
}
Addressables.LoadAssetAsync<SpriteAtlas>(atlasName).Completed += (handle) =>
{
if (handle.Status == AsyncOperationStatus.Succeeded)
{
atlas = handle.Result;
Addressables.Release(handle);
m_SpriteAtlasCache.Add(atlasName, atlas);
}
else
{
Debug.LogError($"图集加载失败 atlasName = {atlasName} Status = {handle.Status}");
callback?.Invoke(null);
}
};
}
/// <summary>
/// 释放所有的资源
/// </summary>
public void ReleaseAll()
{
m_AssetBundles.Clear();
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 01bfbdbb68f24f39bf248e1ce2907783
timeCreated: 1752547273

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 726911973e4b4b129678928347fc1de4
timeCreated: 1752547090

View File

@@ -1,35 +0,0 @@
using System.IO;
using System.Net.Mime;
using Luban;
using UnityEngine;
namespace CreatGame
{
/// <summary>
/// 表格
/// </summary>
public class ConfigManager : Singleton<ConfigManager>
{
/// <summary>
///
/// </summary>
private readonly cfg.Tables tables;
/// <summary>
///
/// </summary>
public cfg.Tables Tables => tables;
public ConfigManager()
{
var tablesCtor = typeof(cfg.Tables).GetConstructors()[0];
// 根据cfg.Tables的构造函数的Loader的返回值类型决定使用json还是ByteBuf Loader
System.Delegate loader = new System.Func<string, ByteBuf>(LoadByteBuf);
tables = (cfg.Tables)tablesCtor.Invoke(new object[] {loader});
}
private static ByteBuf LoadByteBuf(string file)
{
return new ByteBuf(File.ReadAllBytes($"{Application.dataPath}/AssetBundle/Config/{file}.bytes"));
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 60fd032406824917a60af497b179c08f
timeCreated: 1752717676

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8f912db237c54e96b83e9c11a7ab6889
timeCreated: 1752547100

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f208809c54934f6f911cc29d97c3519a
timeCreated: 1752550099

View File

@@ -1,13 +0,0 @@
namespace CreatGame.UI
{
/// <summary>
/// 窗口层级
/// </summary>
public enum UILayer
{
Main,
Popup,
Notify,
System,
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: a02dc47e9bb442079f60800e51c49b6e
timeCreated: 1752551035

View File

@@ -1,76 +0,0 @@
using UnityEngine;
using CreatGame.AssetBundle;
using System.Collections.Generic;
using UnityEngine.U2D;
namespace CreatGame.UI
{
/// <summary>
/// ui上的资源加载器
/// </summary>
public class UILoader
{
private List<GameObject> m_GameObjectCache = new List<GameObject>();
private List<Sprite> m_SpriteCache = new List<Sprite>();
/// <summary>
/// 同步资源加载
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject LoadGameObject(string name)
{
var gameObj = AssetBundleManager.Instance.LoadGameObject(name);
if (gameObj == null)
{
return null;
}
m_GameObjectCache.Add(gameObj);
return gameObj;
}
/// <summary>
/// 异步加载预制件
/// </summary>
/// <param name="name"></param>
/// <param name="callback"></param>
public void LoadGameObjectAsync(string name, System.Action<GameObject> callback)
{
AssetBundleManager.Instance.LoadGameObjectAsync(name, (obj) =>
{
if (obj != null)
{
m_GameObjectCache.Add(obj);
}
callback(obj);
});
}
/// <summary>
///
/// </summary>
/// <param name="atlasName"></param>
/// <param name="spriteName"></param>
/// <returns></returns>
public Sprite LoadSprite(string atlasName, string spriteName)
{
var spriteAtlas = AssetBundleManager.Instance.LoadSpriteAtlas(atlasName);
if (spriteAtlas == null)
{
return null;
}
return spriteAtlas.GetSprite(spriteName);
}
public void DisposeGameObjectCache()
{
var count = m_GameObjectCache.Count;
for (int i = 0; i < count; i++)
{
var obj = m_GameObjectCache[0];
m_GameObjectCache.RemoveAt(0);
GameObject.Destroy(obj);
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: dd77ddfde9dc430eb31244ee82bc2147
timeCreated: 1753323201

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 0631ad95508b427c96e7748c13e0eb59
timeCreated: 1752550115

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: d2e66ce219a441108094ae188afcc745
timeCreated: 1752663372

View File

@@ -1,20 +0,0 @@
using UnityEngine;
using UnityEngine.UI;
namespace CreatGame.UI
{
public class MainItem : MonoBehaviour
{
public Text text;
void ScrollCellIndex (int idx)
{
string name = "Cell " + idx.ToString ();
if (text != null)
{
text.text = name;
}
gameObject.name = name;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 391eb6d877254380bf561b14e4be836f
timeCreated: 1752925668

View File

@@ -1,20 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace CreatGame.UI
{
public partial class UIMainView
{
public override void InitView()
{
base.InitView();
StarBtn.onClick.AddListener(OnStarBtnClick);
}
private void OnStarBtnClick()
{
StarBtnText.text = ConfigManager.Instance.Tables.TbLanguage.Get("Main_BtnTitle_Star").CN;
Debug.Log("OnStarBtnClick");
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 19a056c97ef74d2697f0bd0e7efc3651
timeCreated: 1752663384

View File

@@ -1,29 +0,0 @@
using UnityEngine;
namespace CreatGame.UI
{
/// <summary>
/// 通用的导出预制件的基类
/// </summary>
public class UIComponentBase
{
/// <summary>
/// 窗口预制件
/// </summary>
protected GameObject m_ComponentObject;
/// <summary>
/// 导出脚本
/// </summary>
protected UIComponentExport m_ViewExport;
/// <summary>
/// 是否加载完成
/// </summary>
public bool IsPreLoad = false;
public virtual void PreLoad(GameObject obj)
{
m_ComponentObject = obj;
m_ViewExport = obj.GetComponent<UIComponentExport>();
IsPreLoad = true;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: ba52eedd767b46ae90e720030c75503f
timeCreated: 1752945611

View File

@@ -1,95 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using CreatGame.AssetBundle;
namespace CreatGame.UI
{
public class UIManager : Singleton<UIManager>
{
private GameObject m_UIRoot;
private Dictionary<UILayer,GameObject> m_UILayers;
private Dictionary<UILayer, Queue<UIViewBase>> m_Windows;
/// <summary>
///
/// </summary>
public UIManager()
{
m_UIRoot = GameObject.Find("UIRoot");
InitLayer();
m_Windows = new Dictionary<UILayer, Queue<UIViewBase>>();
}
/// <summary>
/// 初始化layer层的预制件
/// </summary>
private void InitLayer()
{
if (m_UIRoot == null)
{
return;
}
m_UILayers = new Dictionary<UILayer, GameObject>();
foreach (var layer in Enum.GetValues(typeof(UILayer)))
{
var layerObj = m_UIRoot.transform.Find(Enum.GetName(typeof(UILayer), layer)).gameObject;
layerObj.transform.SetParent(m_UIRoot.transform);
layerObj.transform.localScale = Vector3.one;
layerObj.transform.localPosition = Vector3.zero;
layerObj.layer = LayerMask.NameToLayer("UI");
m_UILayers.Add((UILayer)layer,layerObj);
}
}
/// <summary>
///
/// </summary>
/// <param name="layer"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public UIViewBase OpenView<T>(UILayer layer) where T : UIViewBase , new()
{
var view = new T();
//加载预制件
AssetBundleManager.Instance.LoadGameObjectAsync(view.PrefabPath, (obj) =>
{
if (obj == null)
{
Debug.LogError($"窗口加载失败{typeof(T).Name}");
return;
}
view.PreLoad(obj);
if (m_UILayers.TryGetValue(layer, out var uiLayer))
{
obj.transform.SetParent(uiLayer.transform);
obj.transform.localPosition = Vector3.zero;
obj.transform.localScale = Vector3.one;
}
view.InitView();
if (m_Windows.ContainsKey(layer) == false)
{
m_Windows.Add(layer, new Queue<UIViewBase>());
}
m_Windows[layer].Enqueue(view);
});
return view;
}
/// <summary>
///
/// </summary>
/// <param name="layer"></param>
public void CloseView(UILayer layer)
{
if (m_Windows.ContainsKey(layer))
{
var view = m_Windows[layer].Dequeue();
view.CloseView();
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b62361e051d040d696ac9c2485f57a3b
timeCreated: 1752550917

View File

@@ -1,49 +0,0 @@
using UnityEngine;
namespace CreatGame.UI
{
public class UIViewBase : UILoader
{
/// <summary>
/// 预制件的Addressables地址
/// 由导出代码自己添加
/// </summary>
public virtual string PrefabPath { get; set; }
/// <summary>
/// 窗口预制件
/// </summary>
protected GameObject m_ViewObject;
/// <summary>
/// 导出脚本
/// </summary>
protected UIViewExport m_ViewExport;
/// <summary>
/// 是否加载完成
/// </summary>
public bool IsPreLoad = false;
/// <summary>
/// 加载窗口的时候需要预先加载的东西
/// </summary>
public virtual void PreLoad(GameObject viewObject)
{
m_ViewObject = viewObject;
m_ViewExport = viewObject.GetComponent<UIViewExport>();
IsPreLoad = true;
}
/// <summary>
/// 初始化界面
/// </summary>
public virtual void InitView()
{
}
/// <summary>
/// 关闭窗口的时候的调用
/// </summary>
public virtual void CloseView()
{
DisposeGameObjectCache();
GameObject.Destroy(m_ViewObject);
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f48b029bf9fe4664a47a4ede05f4d396
timeCreated: 1752550141

View File

@@ -1,26 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameStar : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
DontDestroyOnLoad(gameObject);
StartCoroutine(CreatGame.GameLogic.Instance.Start());
}
// Update is called once per frame
void Update()
{
}
private void OnDestroy()
{
CreatGame.GameLogic.Instance.Destroy();
}
}

View File

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

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 574ee34052894bd79966fa8ad35a0335
timeCreated: 1752463436

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 05649470a3a64898bac0e32fd05aac14
timeCreated: 1753497036

View File

@@ -1,92 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CreatGame
{
public class CoroutineManager : MonoBehaviour
{
#region Instance
private static CoroutineManager _instance;
public static CoroutineManager Instance
{
get
{
if (_instance == null)
{
var gameObj = new GameObject("CoroutineManager");
_instance = gameObj.AddComponent<CoroutineManager>();
DontDestroyOnLoad(gameObj);
}
return _instance;
}
}
#endregion
private ulong coroutineId = 0;
private ulong GetNextId()
{
return ++coroutineId;
}
private Dictionary<ulong,Coroutine> coroutines = new Dictionary<ulong,Coroutine>();
public ulong StartC(IEnumerator routine)
{
var id = GetNextId();
var coroutine = StartCoroutine(routine);
coroutines.Add(id, coroutine);
return id;
}
/// <summary>
///
/// </summary>
/// <param name="time">间隔时间</param>
/// <param name="isFirst">是否立即执行</param>
/// <param name="loop">是否循环</param>
/// <param name="action">方法</param>
public ulong StartC(float time,bool isFirst , bool loop, Action action)
{
var id = StartC(LoopCoroutine(time,isFirst,loop,action));
return id;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private IEnumerator LoopCoroutine(float time,bool isFirst ,bool loop, Action action)
{
if (isFirst)
{
action.Invoke();
}
while (true)
{
yield return new WaitForSeconds(time);
action.Invoke();
if (!loop)
{
break;
}
}
}
public void StopC(ulong id)
{
if (coroutines.ContainsKey(id))
{
StopCoroutine(coroutines[id]);
coroutines.Remove(id);
}
}
private void OnDestroy()
{
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7089d863c3ed4fb0bc6d7ddcb8488817
timeCreated: 1753497047

View File

@@ -1,36 +0,0 @@
namespace CreatGame
{
public class Singleton<T> where T : class, new()
{
private static T _instance;
private static readonly object _lock = new object();
[UnityEngine.Scripting.Preserve]
protected Singleton()
{
}
/// <summary>
/// 单例对象(线程安全,双重锁定)
/// </summary>
[UnityEngine.Scripting.Preserve]
public static T Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}
}
}

View File

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

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 07fbcc20f70d4d90bce50c964419e32d
timeCreated: 1752636609

View File

@@ -1,38 +0,0 @@
using System;
using UnityEngine;
using System.Collections.Generic;
namespace CreatGame.UI
{
public class UIComponentExport : MonoBehaviour
{
[Serializable]
public class UIEntry
{
public string key;
public GameObject prefab;
public string selectedComponentName; // 存储选择的组件类型名
}
/// <summary>
///
/// </summary>
public List<UIEntry> entries = new List<UIEntry>();
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject GetGameObject(string name)
{
for (int i = 0; i < entries.Count; i++)
{
if (entries[i].key == name)
{
return entries[i].prefab;
}
}
return null;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: d94101161a144f17b4b80530abe93975
timeCreated: 1752945103

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7741c712b36544fc99b98679783c3129
timeCreated: 1753339331

View File

@@ -1,59 +0,0 @@
using System;
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
namespace CreatGame.UI
{
public delegate void OnSelectCallback(int index);
/// <summary>
/// 选中列表
/// </summary>
public class UISelectList : MonoBehaviour
{
public OnSelectCallback onSelectCallback;
private List<Button> m_buttonList = new List<Button>();
private void Awake()
{
m_buttonList = new List<Button>();
}
/// <summary>
///
/// </summary>
private void Start()
{
var childCount= transform.childCount;
for (int i = 0; i < childCount; i++)
{
var button = transform.GetChild(i).GetComponent<Button>();
if (button != null)
{
m_buttonList.Add(button);
button.onClick.AddListener(() => { OnClick(button); });
}
}
}
/// <summary>
///
/// </summary>
/// <param name="btn"></param>
private void OnClick(Button btn)
{
onSelectCallback?.Invoke(m_buttonList.IndexOf(btn));
}
public int Count => m_buttonList.Count;
public Transform this[int index]
{
get
{
if (index < 0 || index >= m_buttonList.Count)
{
return null;
}
return m_buttonList[index].transform;
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 52241bceb69a4f07be09e3dc319276dc
timeCreated: 1753341533

View File

@@ -1,17 +0,0 @@
using UnityEngine;
namespace CreatGame.UI
{
public class UISelected : MonoBehaviour
{
public int index = -1;
/// <summary>
/// 选中状态
/// </summary>
public GameObject selected;
/// <summary>
/// 未选中状态
/// </summary>
public GameObject unSelected;
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 20f38d816dc54bcb9ef57888b31a481d
timeCreated: 1753339357

View File

@@ -1,29 +0,0 @@
using System;
using UnityEngine;
using System.Collections.Generic;
public class UIViewExport : MonoBehaviour
{
[Serializable]
public class UIEntry
{
public string key;
public GameObject prefab;
public string selectedComponentName; // 存储选择的组件类型名
}
public List<UIEntry> entries = new List<UIEntry>();
public GameObject GetGameObject(string name)
{
for (int i = 0; i < entries.Count; i++)
{
if (entries[i].key == name)
{
return entries[i].prefab;
}
}
return null;
}
}

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f84e74ce6787f864eb11f18e939b1fc9
guid: 217bb07fcea56ab42b8e338a8d59c9a7
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,99 @@
using UnityEngine;
using System;
#if UNITY_EDITOR
using System.Reflection;
#endif
public static class ConsoleProDebug
{
// Clear the console and the native console
public static void Clear()
{
#if UNITY_EDITOR
if(ConsoleClearMethod != null)
{
ConsoleClearMethod.Invoke(null, null);
}
#endif
}
// Send a log to a specific filter regardless of contents
// Ex: ConsoleProDebug.LogToFilter("Hi", "CustomFilter");
public static void LogToFilter(string inLog, string inFilterName, UnityEngine.Object inContext = null)
{
Debug.Log(inLog + "\nCPAPI:{\"cmd\":\"Filter\", \"name\":\"" + inFilterName + "\"}", inContext);
}
// Send a log as a regular log but change its type in ConsolePro
// Ex: ConsoleProDebug.LogAsType("Hi", "Error");
public static void LogAsType(string inLog, string inTypeName, UnityEngine.Object inContext = null)
{
Debug.Log(inLog + "\nCPAPI:{\"cmd\":\"LogType\", \"name\":\"" + inTypeName + "\"}", inContext);
}
// Watch a variable. This will only produce one log entry regardless of how many times it is logged, allowing you to track variables without spam.
// Ex:
// void Update() {
// ConsoleProDebug.Watch("Player X Position", transform.position.x);
// }
public static void Watch(string inName, string inValue)
{
Debug.Log(inName + " : " + inValue + "\nCPAPI:{\"cmd\":\"Watch\", \"name\":\"" + inName + "\"}");
}
public static void Search(string inText)
{
Debug.Log("\nCPAPI:{\"cmd\":\"Search\", \"text\":\"" + inText + "\"}");
}
#if UNITY_EDITOR
// Reflection calls to access Console Pro from runtime
private static bool _checkedConsoleClearMethod = false;
private static MethodInfo _consoleClearMethod = null;
private static MethodInfo ConsoleClearMethod
{
get
{
if(_consoleClearMethod == null || !_checkedConsoleClearMethod)
{
_checkedConsoleClearMethod = true;
if(ConsoleWindowType == null)
{
return null;
}
_consoleClearMethod = ConsoleWindowType.GetMethod("ClearEntries", BindingFlags.Static | BindingFlags.Public);
}
return _consoleClearMethod;
}
}
private static bool _checkedConsoleWindowType = false;
private static Type _consoleWindowType = null;
private static Type ConsoleWindowType
{
get
{
if(_consoleWindowType == null || !_checkedConsoleWindowType)
{
_checkedConsoleWindowType = true;
Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
for(int iAssembly = 0; iAssembly < assemblies.Length; iAssembly++)
{
Type[] types = assemblies[iAssembly].GetTypes();
for(int iType = 0; iType < types.Length; iType++)
{
if(types[iType].Name == "ConsolePro3Window")
{
_consoleWindowType = types[iType];
}
}
}
}
return _consoleWindowType;
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 30f42e8a12eb842acbe9a63057fb00e4
timeCreated: 1469329295
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5de782a9528f04b41a8ba70afba32a61
timeCreated: 1498113024
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1dce5d6d618839f4f9e0e9d32c5d0699
guid: 4bb9fa3b2a6b341a9af20d3b5f03ee13
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: a2284c517ee274c19a6ba4c1a8c96fb6
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3f14d07c8a9074483a59436a3caaad09
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,249 @@
// Uncomment to use in Editor
#define USECONSOLEPROREMOTESERVERINEDITOR
// #if (UNITY_WP_8_1 || UNITY_WSA)
// #define UNSUPPORTEDCONSOLEPROREMOTESERVER
// #endif
#if (!UNITY_EDITOR && DEBUG) || (UNITY_EDITOR && USECONSOLEPROREMOTESERVERINEDITOR)
#if !UNSUPPORTEDCONSOLEPROREMOTESERVER
#define USECONSOLEPROREMOTESERVER
#endif
#endif
#if UNITY_EDITOR && !USECONSOLEPROREMOTESERVER
#elif UNSUPPORTEDCONSOLEPROREMOTESERVER
#elif !USECONSOLEPROREMOTESERVER
#else
using System;
using System.Collections.Generic;
#endif
using System.Net;
using System.Net.Sockets;
using UnityEngine;
#if USECONSOLEPROREMOTESERVER
using FlyingWormConsole3.LiteNetLib;
using FlyingWormConsole3.LiteNetLib.Utils;
#endif
namespace FlyingWormConsole3
{
#if USECONSOLEPROREMOTESERVER
public class ConsoleProRemoteServer : MonoBehaviour, INetEventListener
#else
public class ConsoleProRemoteServer : MonoBehaviour
#endif
{
public bool useNATPunch = false;
public int port = 51000;
#if UNITY_EDITOR && !USECONSOLEPROREMOTESERVER
#elif UNSUPPORTEDCONSOLEPROREMOTESERVER
public void Awake()
{
Debug.Log("Console Pro Remote Server is not supported on this platform");
}
#elif !USECONSOLEPROREMOTESERVER
public void Awake()
{
Debug.Log("Console Pro Remote Server is disabled in release mode, please use a Development build or define DEBUG to use it");
}
#else
private NetManager _netServer;
private NetPeer _ourPeer;
private NetDataWriter _dataWriter;
[System.SerializableAttribute]
public class QueuedLog
{
public string timestamp;
public string message;
public string logType;
}
[NonSerializedAttribute]
public List<QueuedLog> logs = new List<QueuedLog>();
private static ConsoleProRemoteServer instance = null;
void Awake()
{
if(instance != null)
{
Destroy(gameObject);
}
instance = this;
DontDestroyOnLoad(gameObject);
Debug.Log("#Remote# Starting Console Pro Server on port : " + port);
_dataWriter = new NetDataWriter();
_netServer = new NetManager(this);
_netServer.Start(port);
_netServer.BroadcastReceiveEnabled = true;
_netServer.UpdateTime = 15;
_netServer.NatPunchEnabled = useNATPunch;
}
void OnDestroy()
{
if(_netServer != null)
{
_netServer.Stop();
}
}
public void OnPeerConnected(NetPeer peer)
{
Debug.Log("#Remote# Connected to " + peer.EndPoint);
_ourPeer = peer;
}
public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
{
Debug.Log("#Remote# Disconnected from " + peer.EndPoint + ", info: " + disconnectInfo.Reason);
if (peer == _ourPeer)
{
_ourPeer = null;
}
}
public void OnNetworkError(IPEndPoint endPoint, SocketError socketError)
{
// throw new NotImplementedException();
}
public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
{
// throw new NotImplementedException();
}
public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
{
if(messageType == UnconnectedMessageType.Broadcast)
{
// Debug.Log("#Remote# Received discovery request. Send discovery response");
_netServer.SendUnconnectedMessage(new byte[] {1}, remoteEndPoint);
}
}
public void OnPeerDisconnected(NetPeer peer, DisconnectReason reason, int socketErrorCode)
{
}
public void OnNetworkLatencyUpdate(NetPeer peer, int latency)
{
}
public void OnConnectionRequest(ConnectionRequest request)
{
// Debug.Log("#Remote# Connection requested, accepting");
request.AcceptIfKey("Console Pro");
}
#if UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
void OnEnable()
{
Application.RegisterLogCallback(LogCallback);
}
void Update()
{
Application.RegisterLogCallback(LogCallback);
}
void OnDisable()
{
Application.RegisterLogCallback(null);
}
#else
void OnEnable()
{
Application.logMessageReceivedThreaded += LogCallback;
}
void OnDisable()
{
Application.logMessageReceivedThreaded -= LogCallback;
}
#endif
public void LogCallback(string logString, string stackTrace, LogType type)
{
if(!logString.StartsWith("CPIGNORE"))
{
QueueLog(logString, stackTrace, type);
}
}
void QueueLog(string logString, string stackTrace, LogType type)
{
if(logs.Count > 1000)
{
while(logs.Count > 1000)
{
logs.RemoveAt(0);
}
}
#if CSHARP_7_3_OR_NEWER
logString = $"{logString}\n{stackTrace}\n";
logs.Add(new QueuedLog() { message = logString, logType = type.ToString(), timestamp = $"[{DateTime.Now.ToString("HH:mm:ss")}]" } );
#else
logString = logString + "\n" + stackTrace + "\n";
logs.Add(new QueuedLog() { message = logString, logType = type.ToString(), timestamp = "[" + DateTime.Now.ToString("HH:mm:ss") + "]" } );
#endif
}
void LateUpdate()
{
if(_netServer == null)
{
return;
}
_netServer.PollEvents();
if(_ourPeer == null)
{
return;
}
if(logs.Count <= 0)
{
return;
}
string cMessage = "";
foreach(var cLog in logs)
{
cMessage = JsonUtility.ToJson(cLog);
_dataWriter.Reset();
_dataWriter.Put(cMessage);
_ourPeer.Send(_dataWriter, DeliveryMethod.ReliableOrdered);
}
logs.Clear();
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d6bcfaced529e418bb75980b297fda2a
timeCreated: 1437614101
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2c6bd635eeaa04c228b6d342c4758ad7
folderAsset: yes
timeCreated: 1494014730
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
using System.Threading;
namespace FlyingWormConsole3.LiteNetLib
{
internal abstract class BaseChannel
{
protected readonly NetPeer Peer;
protected readonly Queue<NetPacket> OutgoingQueue;
private int _isAddedToPeerChannelSendQueue;
public int PacketsInQueue
{
get { return OutgoingQueue.Count; }
}
protected BaseChannel(NetPeer peer)
{
Peer = peer;
OutgoingQueue = new Queue<NetPacket>(64);
}
public void AddToQueue(NetPacket packet)
{
lock (OutgoingQueue)
{
OutgoingQueue.Enqueue(packet);
}
AddToPeerChannelSendQueue();
}
protected void AddToPeerChannelSendQueue()
{
if (Interlocked.CompareExchange(ref _isAddedToPeerChannelSendQueue, 1, 0) == 0)
{
Peer.AddToReliableChannelSendQueue(this);
}
}
public bool SendAndCheckQueue()
{
bool hasPacketsToSend = SendNextPackets();
if (!hasPacketsToSend)
Interlocked.Exchange(ref _isAddedToPeerChannelSendQueue, 0);
return hasPacketsToSend;
}
protected abstract bool SendNextPackets();
public abstract bool ProcessPacket(NetPacket packet);
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a19e815a8e895d44d8ecd983ec7322a2
guid: 763566e7d03d94946afed98596540971
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,137 @@
using System.Net;
using System.Threading;
using FlyingWormConsole3.LiteNetLib.Utils;
namespace FlyingWormConsole3.LiteNetLib
{
internal enum ConnectionRequestResult
{
None,
Accept,
Reject,
RejectForce
}
public class ConnectionRequest
{
private readonly NetManager _listener;
private int _used;
public readonly NetDataReader Data;
internal ConnectionRequestResult Result { get; private set; }
internal long ConnectionTime;
internal byte ConnectionNumber;
public readonly IPEndPoint RemoteEndPoint;
private bool TryActivate()
{
return Interlocked.CompareExchange(ref _used, 1, 0) == 0;
}
internal void UpdateRequest(NetConnectRequestPacket connRequest)
{
if (connRequest.ConnectionTime >= ConnectionTime)
{
ConnectionTime = connRequest.ConnectionTime;
ConnectionNumber = connRequest.ConnectionNumber;
}
}
internal ConnectionRequest(
long connectionId,
byte connectionNumber,
NetDataReader netDataReader,
IPEndPoint endPoint,
NetManager listener)
{
ConnectionTime = connectionId;
ConnectionNumber = connectionNumber;
RemoteEndPoint = endPoint;
Data = netDataReader;
_listener = listener;
}
public NetPeer AcceptIfKey(string key)
{
if (!TryActivate())
return null;
try
{
if (Data.GetString() == key)
Result = ConnectionRequestResult.Accept;
}
catch
{
NetDebug.WriteError("[AC] Invalid incoming data");
}
if (Result == ConnectionRequestResult.Accept)
return _listener.OnConnectionSolved(this, null, 0, 0);
Result = ConnectionRequestResult.Reject;
_listener.OnConnectionSolved(this, null, 0, 0);
return null;
}
/// <summary>
/// Accept connection and get new NetPeer as result
/// </summary>
/// <returns>Connected NetPeer</returns>
public NetPeer Accept()
{
if (!TryActivate())
return null;
Result = ConnectionRequestResult.Accept;
return _listener.OnConnectionSolved(this, null, 0, 0);
}
public void Reject(byte[] rejectData, int start, int length, bool force)
{
if (!TryActivate())
return;
Result = force ? ConnectionRequestResult.RejectForce : ConnectionRequestResult.Reject;
_listener.OnConnectionSolved(this, rejectData, start, length);
}
public void Reject(byte[] rejectData, int start, int length)
{
Reject(rejectData, start, length, false);
}
public void RejectForce(byte[] rejectData, int start, int length)
{
Reject(rejectData, start, length, true);
}
public void RejectForce()
{
Reject(null, 0, 0, true);
}
public void RejectForce(byte[] rejectData)
{
Reject(rejectData, 0, rejectData.Length, true);
}
public void RejectForce(NetDataWriter rejectData)
{
Reject(rejectData.Data, 0, rejectData.Length, true);
}
public void Reject()
{
Reject(null, 0, 0, false);
}
public void Reject(byte[] rejectData)
{
Reject(rejectData, 0, rejectData.Length, false);
}
public void Reject(NetDataWriter rejectData)
{
Reject(rejectData.Data, 0, rejectData.Length, false);
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b01c530301ff8ad4191edef0fdbb9434
guid: 01553ccc867ec43bbb1ae69d3de1ddda
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,247 @@
using System.Net;
using System.Net.Sockets;
using FlyingWormConsole3.LiteNetLib.Utils;
namespace FlyingWormConsole3.LiteNetLib
{
/// <summary>
/// Type of message that you receive in OnNetworkReceiveUnconnected event
/// </summary>
public enum UnconnectedMessageType
{
BasicMessage,
Broadcast
}
/// <summary>
/// Disconnect reason that you receive in OnPeerDisconnected event
/// </summary>
public enum DisconnectReason
{
ConnectionFailed,
Timeout,
HostUnreachable,
NetworkUnreachable,
RemoteConnectionClose,
DisconnectPeerCalled,
ConnectionRejected,
InvalidProtocol,
UnknownHost,
Reconnect,
PeerToPeerConnection
}
/// <summary>
/// Additional information about disconnection
/// </summary>
public struct DisconnectInfo
{
/// <summary>
/// Additional info why peer disconnected
/// </summary>
public DisconnectReason Reason;
/// <summary>
/// Error code (if reason is SocketSendError or SocketReceiveError)
/// </summary>
public SocketError SocketErrorCode;
/// <summary>
/// Additional data that can be accessed (only if reason is RemoteConnectionClose)
/// </summary>
public NetPacketReader AdditionalData;
}
public interface INetEventListener
{
/// <summary>
/// New remote peer connected to host, or client connected to remote host
/// </summary>
/// <param name="peer">Connected peer object</param>
void OnPeerConnected(NetPeer peer);
/// <summary>
/// Peer disconnected
/// </summary>
/// <param name="peer">disconnected peer</param>
/// <param name="disconnectInfo">additional info about reason, errorCode or data received with disconnect message</param>
void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);
/// <summary>
/// Network error (on send or receive)
/// </summary>
/// <param name="endPoint">From endPoint (can be null)</param>
/// <param name="socketError">Socket error</param>
void OnNetworkError(IPEndPoint endPoint, SocketError socketError);
/// <summary>
/// Received some data
/// </summary>
/// <param name="peer">From peer</param>
/// <param name="reader">DataReader containing all received data</param>
/// <param name="deliveryMethod">Type of received packet</param>
void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod);
/// <summary>
/// Received unconnected message
/// </summary>
/// <param name="remoteEndPoint">From address (IP and Port)</param>
/// <param name="reader">Message data</param>
/// <param name="messageType">Message type (simple, discovery request or response)</param>
void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType);
/// <summary>
/// Latency information updated
/// </summary>
/// <param name="peer">Peer with updated latency</param>
/// <param name="latency">latency value in milliseconds</param>
void OnNetworkLatencyUpdate(NetPeer peer, int latency);
/// <summary>
/// On peer connection requested
/// </summary>
/// <param name="request">Request information (EndPoint, internal id, additional data)</param>
void OnConnectionRequest(ConnectionRequest request);
}
public interface IDeliveryEventListener
{
/// <summary>
/// On reliable message delivered
/// </summary>
/// <param name="peer"></param>
/// <param name="userData"></param>
void OnMessageDelivered(NetPeer peer, object userData);
}
public interface INtpEventListener
{
/// <summary>
/// Ntp response
/// </summary>
/// <param name="packet"></param>
void OnNtpResponse(NtpPacket packet);
}
public class EventBasedNetListener : INetEventListener, IDeliveryEventListener, INtpEventListener
{
public delegate void OnPeerConnected(NetPeer peer);
public delegate void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo);
public delegate void OnNetworkError(IPEndPoint endPoint, SocketError socketError);
public delegate void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod);
public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType);
public delegate void OnNetworkLatencyUpdate(NetPeer peer, int latency);
public delegate void OnConnectionRequest(ConnectionRequest request);
public delegate void OnDeliveryEvent(NetPeer peer, object userData);
public delegate void OnNtpResponseEvent(NtpPacket packet);
public event OnPeerConnected PeerConnectedEvent;
public event OnPeerDisconnected PeerDisconnectedEvent;
public event OnNetworkError NetworkErrorEvent;
public event OnNetworkReceive NetworkReceiveEvent;
public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent;
public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent;
public event OnConnectionRequest ConnectionRequestEvent;
public event OnDeliveryEvent DeliveryEvent;
public event OnNtpResponseEvent NtpResponseEvent;
public void ClearPeerConnectedEvent()
{
PeerConnectedEvent = null;
}
public void ClearPeerDisconnectedEvent()
{
PeerDisconnectedEvent = null;
}
public void ClearNetworkErrorEvent()
{
NetworkErrorEvent = null;
}
public void ClearNetworkReceiveEvent()
{
NetworkReceiveEvent = null;
}
public void ClearNetworkReceiveUnconnectedEvent()
{
NetworkReceiveUnconnectedEvent = null;
}
public void ClearNetworkLatencyUpdateEvent()
{
NetworkLatencyUpdateEvent = null;
}
public void ClearConnectionRequestEvent()
{
ConnectionRequestEvent = null;
}
public void ClearDeliveryEvent()
{
DeliveryEvent = null;
}
public void ClearNtpResponseEvent()
{
NtpResponseEvent = null;
}
void INetEventListener.OnPeerConnected(NetPeer peer)
{
if (PeerConnectedEvent != null)
PeerConnectedEvent(peer);
}
void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
{
if (PeerDisconnectedEvent != null)
PeerDisconnectedEvent(peer, disconnectInfo);
}
void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode)
{
if (NetworkErrorEvent != null)
NetworkErrorEvent(endPoint, socketErrorCode);
}
void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
{
if (NetworkReceiveEvent != null)
NetworkReceiveEvent(peer, reader, deliveryMethod);
}
void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
{
if (NetworkReceiveUnconnectedEvent != null)
NetworkReceiveUnconnectedEvent(remoteEndPoint, reader, messageType);
}
void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency)
{
if (NetworkLatencyUpdateEvent != null)
NetworkLatencyUpdateEvent(peer, latency);
}
void INetEventListener.OnConnectionRequest(ConnectionRequest request)
{
if (ConnectionRequestEvent != null)
ConnectionRequestEvent(request);
}
void IDeliveryEventListener.OnMessageDelivered(NetPeer peer, object userData)
{
if (DeliveryEvent != null)
DeliveryEvent(peer, userData);
}
void INtpEventListener.OnNtpResponse(NtpPacket packet)
{
if (NtpResponseEvent != null)
NtpResponseEvent(packet);
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8fc14253f6e36724eb657932e1084248
guid: d391f9565d58e44a798d680ec5c11906
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 38985fb72fd8c40eb9de4ce7bfaf401b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
using FlyingWormConsole3.LiteNetLib.Utils;
using System;
using System.Net;
namespace FlyingWormConsole3.LiteNetLib.Layers
{
public sealed class Crc32cLayer : PacketLayerBase
{
public Crc32cLayer() : base(CRC32C.ChecksumSize)
{
}
public override void ProcessInboundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
{
if (length < NetConstants.HeaderSize + CRC32C.ChecksumSize)
{
NetDebug.WriteError("[NM] DataReceived size: bad!");
//Set length to 0 to have netManager drop the packet.
length = 0;
return;
}
int checksumPoint = length - CRC32C.ChecksumSize;
if (CRC32C.Compute(data, offset, checksumPoint) != BitConverter.ToUInt32(data, checksumPoint))
{
NetDebug.Write("[NM] DataReceived checksum: bad!");
//Set length to 0 to have netManager drop the packet.
length = 0;
return;
}
length -= CRC32C.ChecksumSize;
}
public override void ProcessOutBoundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
{
FastBitConverter.GetBytes(data, length, CRC32C.Compute(data, offset, length));
length += CRC32C.ChecksumSize;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 43eea21323b017e498f0f0f6de63abf7
guid: 03f6f2696c6e848c69a6af33539c5adc
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,17 @@
using System.Net;
namespace FlyingWormConsole3.LiteNetLib.Layers
{
public abstract class PacketLayerBase
{
public readonly int ExtraPacketSizeForLayer;
protected PacketLayerBase(int extraPacketSizeForLayer)
{
ExtraPacketSizeForLayer = extraPacketSizeForLayer;
}
public abstract void ProcessInboundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length);
public abstract void ProcessOutBoundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length);
}
}

View File

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

View File

@@ -0,0 +1,60 @@
using System;
using System.Net;
using System.Text;
namespace FlyingWormConsole3.LiteNetLib.Layers
{
public class XorEncryptLayer : PacketLayerBase
{
private byte[] _byteKey;
public XorEncryptLayer() : base(0)
{
}
public XorEncryptLayer(byte[] key) : this()
{
SetKey(key);
}
public XorEncryptLayer(string key) : this()
{
SetKey(key);
}
public void SetKey(string key)
{
_byteKey = Encoding.UTF8.GetBytes(key);
}
public void SetKey(byte[] key)
{
if (_byteKey == null || _byteKey.Length != key.Length)
_byteKey = new byte[key.Length];
Buffer.BlockCopy(key, 0, _byteKey, 0, key.Length);
}
public override void ProcessInboundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
{
if (_byteKey == null)
return;
var cur = offset;
for (var i = 0; i < length; i++, cur++)
{
data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]);
}
}
public override void ProcessOutBoundPacket(IPEndPoint endPoint, ref byte[] data, ref int offset, ref int length)
{
if (_byteKey == null)
return;
var cur = offset;
for (var i = 0; i < length; i++, cur++)
{
data[cur] = (byte)(data[cur] ^ _byteKey[i % _byteKey.Length]);
}
}
}
}

View File

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

View File

@@ -0,0 +1,245 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using FlyingWormConsole3.LiteNetLib.Utils;
namespace FlyingWormConsole3.LiteNetLib
{
public enum NatAddressType
{
Internal,
External
}
public interface INatPunchListener
{
void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token);
void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token);
}
public class EventBasedNatPunchListener : INatPunchListener
{
public delegate void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token);
public delegate void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token);
public event OnNatIntroductionRequest NatIntroductionRequest;
public event OnNatIntroductionSuccess NatIntroductionSuccess;
void INatPunchListener.OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token)
{
if(NatIntroductionRequest != null)
NatIntroductionRequest(localEndPoint, remoteEndPoint, token);
}
void INatPunchListener.OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token)
{
if (NatIntroductionSuccess != null)
NatIntroductionSuccess(targetEndPoint, type, token);
}
}
/// <summary>
/// Module for UDP NAT Hole punching operations. Can be accessed from NetManager
/// </summary>
public sealed class NatPunchModule
{
struct RequestEventData
{
public IPEndPoint LocalEndPoint;
public IPEndPoint RemoteEndPoint;
public string Token;
}
struct SuccessEventData
{
public IPEndPoint TargetEndPoint;
public NatAddressType Type;
public string Token;
}
class NatIntroduceRequestPacket
{
public IPEndPoint Internal { get; set; }
public string Token { get; set; }
}
class NatIntroduceResponsePacket
{
public IPEndPoint Internal { get; set; }
public IPEndPoint External { get; set; }
public string Token { get; set; }
}
class NatPunchPacket
{
public string Token { get; set; }
public bool IsExternal { get; set; }
}
private readonly NetSocket _socket;
private readonly Queue<RequestEventData> _requestEvents = new Queue<RequestEventData>();
private readonly Queue<SuccessEventData> _successEvents = new Queue<SuccessEventData>();
private readonly NetDataReader _cacheReader = new NetDataReader();
private readonly NetDataWriter _cacheWriter = new NetDataWriter();
private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(MaxTokenLength);
private INatPunchListener _natPunchListener;
public const int MaxTokenLength = 256;
internal NatPunchModule(NetSocket socket)
{
_socket = socket;
_netPacketProcessor.SubscribeReusable<NatIntroduceResponsePacket>(OnNatIntroductionResponse);
_netPacketProcessor.SubscribeReusable<NatIntroduceRequestPacket, IPEndPoint>(OnNatIntroductionRequest);
_netPacketProcessor.SubscribeReusable<NatPunchPacket, IPEndPoint>(OnNatPunch);
}
internal void ProcessMessage(IPEndPoint senderEndPoint, NetPacket packet)
{
lock (_cacheReader)
{
_cacheReader.SetSource(packet.RawData, NetConstants.HeaderSize, packet.Size);
_netPacketProcessor.ReadAllPackets(_cacheReader, senderEndPoint);
}
}
public void Init(INatPunchListener listener)
{
_natPunchListener = listener;
}
private void Send<T>(T packet, IPEndPoint target) where T : class, new()
{
SocketError errorCode = 0;
_cacheWriter.Reset();
_cacheWriter.Put((byte)PacketProperty.NatMessage);
_netPacketProcessor.Write(_cacheWriter, packet);
_socket.SendTo(_cacheWriter.Data, 0, _cacheWriter.Length, target, ref errorCode);
}
public void NatIntroduce(
IPEndPoint hostInternal,
IPEndPoint hostExternal,
IPEndPoint clientInternal,
IPEndPoint clientExternal,
string additionalInfo)
{
var req = new NatIntroduceResponsePacket
{
Token = additionalInfo
};
//First packet (server) send to client
req.Internal = hostInternal;
req.External = hostExternal;
Send(req, clientExternal);
//Second packet (client) send to server
req.Internal = clientInternal;
req.External = clientExternal;
Send(req, hostExternal);
}
public void PollEvents()
{
if (_natPunchListener == null || (_successEvents.Count == 0 && _requestEvents.Count == 0))
return;
lock (_successEvents)
{
while (_successEvents.Count > 0)
{
var evt = _successEvents.Dequeue();
_natPunchListener.OnNatIntroductionSuccess(
evt.TargetEndPoint,
evt.Type,
evt.Token);
}
}
lock (_requestEvents)
{
while (_requestEvents.Count > 0)
{
var evt = _requestEvents.Dequeue();
_natPunchListener.OnNatIntroductionRequest(evt.LocalEndPoint, evt.RemoteEndPoint, evt.Token);
}
}
}
public void SendNatIntroduceRequest(string host, int port, string additionalInfo)
{
SendNatIntroduceRequest(NetUtils.MakeEndPoint(host, port), additionalInfo);
}
public void SendNatIntroduceRequest(IPEndPoint masterServerEndPoint, string additionalInfo)
{
//prepare outgoing data
string networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv4);
if (string.IsNullOrEmpty(networkIp))
{
networkIp = NetUtils.GetLocalIp(LocalAddrType.IPv6);
}
Send(
new NatIntroduceRequestPacket
{
Internal = NetUtils.MakeEndPoint(networkIp, _socket.LocalPort),
Token = additionalInfo
},
masterServerEndPoint);
}
//We got request and must introduce
private void OnNatIntroductionRequest(NatIntroduceRequestPacket req, IPEndPoint senderEndPoint)
{
lock (_requestEvents)
{
_requestEvents.Enqueue(new RequestEventData
{
LocalEndPoint = req.Internal,
RemoteEndPoint = senderEndPoint,
Token = req.Token
});
}
}
//We got introduce and must punch
private void OnNatIntroductionResponse(NatIntroduceResponsePacket req)
{
NetDebug.Write(NetLogLevel.Trace, "[NAT] introduction received");
// send internal punch
var punchPacket = new NatPunchPacket {Token = req.Token};
Send(punchPacket, req.Internal);
NetDebug.Write(NetLogLevel.Trace, "[NAT] internal punch sent to " + req.Internal);
// hack for some routers
SocketError errorCode = 0;
_socket.Ttl = 2;
_socket.SendTo(new[] { (byte)PacketProperty.Empty }, 0, 1, req.External, ref errorCode);
// send external punch
_socket.Ttl = NetConstants.SocketTTL;
punchPacket.IsExternal = true;
Send(punchPacket, req.External);
NetDebug.Write(NetLogLevel.Trace, "[NAT] external punch sent to " + req.External);
}
//We got punch and can connect
private void OnNatPunch(NatPunchPacket req, IPEndPoint senderEndPoint)
{
//Read info
NetDebug.Write(NetLogLevel.Trace, "[NAT] punch received from {0} - additional info: {1}",
senderEndPoint, req.Token);
//Release punch success to client; enabling him to Connect() to Sender if token is ok
lock (_successEvents)
{
_successEvents.Enqueue(new SuccessEventData
{
TargetEndPoint = senderEndPoint,
Type = req.IsExternal ? NatAddressType.External : NatAddressType.Internal,
Token = req.Token
});
}
}
}
}

View File

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

View File

@@ -0,0 +1,74 @@
namespace FlyingWormConsole3.LiteNetLib
{
/// <summary>
/// Sending method type
/// </summary>
public enum DeliveryMethod : byte
{
/// <summary>
/// Unreliable. Packets can be dropped, can be duplicated, can arrive without order.
/// </summary>
Unreliable = 4,
/// <summary>
/// Reliable. Packets won't be dropped, won't be duplicated, can arrive without order.
/// </summary>
ReliableUnordered = 0,
/// <summary>
/// Unreliable. Packets can be dropped, won't be duplicated, will arrive in order.
/// </summary>
Sequenced = 1,
/// <summary>
/// Reliable and ordered. Packets won't be dropped, won't be duplicated, will arrive in order.
/// </summary>
ReliableOrdered = 2,
/// <summary>
/// Reliable only last packet. Packets can be dropped (except the last one), won't be duplicated, will arrive in order.
/// Cannot be fragmented
/// </summary>
ReliableSequenced = 3
}
/// <summary>
/// Network constants. Can be tuned from sources for your purposes.
/// </summary>
public static class NetConstants
{
//can be tuned
public const int DefaultWindowSize = 64;
public const int SocketBufferSize = 1024 * 1024; //1mb
public const int SocketTTL = 255;
public const int HeaderSize = 1;
public const int ChanneledHeaderSize = 4;
public const int FragmentHeaderSize = 6;
public const int FragmentedHeaderTotalSize = ChanneledHeaderSize + FragmentHeaderSize;
public const ushort MaxSequence = 32768;
public const ushort HalfMaxSequence = MaxSequence / 2;
//protocol
internal const int ProtocolId = 11;
internal const int MaxUdpHeaderSize = 68;
internal static readonly int[] PossibleMtu =
{
576 - MaxUdpHeaderSize, //minimal (RFC 1191)
1024, //most games standard
1232 - MaxUdpHeaderSize,
1460 - MaxUdpHeaderSize, //google cloud
1472 - MaxUdpHeaderSize, //VPN
1492 - MaxUdpHeaderSize, //Ethernet with LLC and SNAP, PPPoE (RFC 1042)
1500 - MaxUdpHeaderSize //Ethernet II (RFC 1191)
};
internal static readonly int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1];
//peer specific
public const byte MaxConnectionNumber = 4;
public const int PacketPoolSize = 1000;
}
}

View File

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

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