248 lines
8.8 KiB
C#
248 lines
8.8 KiB
C#
//
|
||
// Proto2CSEditor.cs
|
||
//
|
||
// Author:
|
||
// JasonXuDeveloper(傑) <jasonxudeveloper@gmail.com>
|
||
//
|
||
// Copyright (c) 2020 JEngine
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
// of this software and associated documentation files (the "Software"), to deal
|
||
// in the Software without restriction, including without limitation the rights
|
||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
// copies of the Software, and to permit persons to whom the Software is
|
||
// furnished to do so, subject to the following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included in
|
||
// all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
// THE SOFTWARE.
|
||
|
||
using System.IO;
|
||
using Google.Protobuf.Reflection;
|
||
using ProtoBuf.Reflection;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace Guru
|
||
{
|
||
internal class Proto2CSEditor : EditorWindow
|
||
{
|
||
private static Proto2CSEditor win;
|
||
|
||
//[MenuItem("Tools/Protobuf/Show Generate Window")]
|
||
//public static void ShowCSGenerateWindow()
|
||
//{
|
||
// int index = Application.dataPath.LastIndexOf('/');
|
||
// var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
|
||
// win = GetWindow<Proto2CSEditor>("Proto2CS Generator");
|
||
// win.folder = EditorUtility.OpenFolderPanel("Please select proto files directory",
|
||
// proto_dir, "");
|
||
// win.minSize = new Vector2(500, 500);
|
||
// win.Show();
|
||
//}
|
||
|
||
[MenuItem("Tools/Protobuf/Generate All")]
|
||
public static void GenerateAllProtos()
|
||
{
|
||
int index = Application.dataPath.LastIndexOf('/');
|
||
var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
|
||
var file_list = GetAllProtoFiles(proto_dir);
|
||
var dest_folder = $"{Application.dataPath}/../Assets/Scripts/NetworkGen";
|
||
|
||
if (Directory.Exists(dest_folder))
|
||
{
|
||
Directory.Delete(dest_folder, true);
|
||
|
||
// Just in case the system has output_folder still locked for deletion
|
||
while (Directory.Exists(dest_folder))
|
||
{
|
||
System.Threading.Thread.Sleep(10);
|
||
}
|
||
}
|
||
|
||
Directory.CreateDirectory(dest_folder);
|
||
|
||
Generate(proto_dir, file_list, dest_folder);
|
||
}
|
||
|
||
[MenuItem("Tools/Protobuf/View Proto Files")]
|
||
private static void ViewDataPath()
|
||
{
|
||
int index = Application.dataPath.LastIndexOf('/');
|
||
var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
|
||
|
||
if (!Directory.Exists(proto_dir))
|
||
{
|
||
Directory.CreateDirectory(proto_dir);
|
||
}
|
||
|
||
EditorUtility.OpenWithDefaultApp(proto_dir);
|
||
}
|
||
|
||
[SerializeField] protected string[] _fileList = new string[0];
|
||
protected string folder;
|
||
protected SerializedObject _serializedObject;
|
||
protected SerializedProperty _fileListProperty;
|
||
|
||
|
||
protected void OnEnable()
|
||
{
|
||
//使用当前类初始化
|
||
_serializedObject = new SerializedObject(this);
|
||
//获取当前类中可序列话的属性
|
||
_fileListProperty = _serializedObject.FindProperty("_fileList");
|
||
}
|
||
|
||
protected void OnGUI()
|
||
{
|
||
//绘制标题
|
||
GUILayout.Space(10);
|
||
GUIStyle textStyle = new GUIStyle();
|
||
textStyle.fontSize = 24;
|
||
textStyle.normal.textColor = Color.white;
|
||
textStyle.alignment = TextAnchor.MiddleCenter;
|
||
GUILayout.Label("Proto文件转CS文件", textStyle);
|
||
textStyle.fontSize = 18;
|
||
GUILayout.Label("Proto file to CS file", textStyle);
|
||
GUILayout.Space(10);
|
||
|
||
/*
|
||
* 路径
|
||
*/
|
||
GUILayout.Label("Proto file folder Proto文件路径");
|
||
GUILayout.BeginHorizontal();
|
||
EditorGUI.BeginDisabledGroup(true);
|
||
folder = EditorGUILayout.TextField(folder);
|
||
EditorGUI.EndDisabledGroup();
|
||
|
||
GUILayout.Space(10);
|
||
if (GUILayout.Button("Select Path 选择路径", GUILayout.ExpandWidth(false)))
|
||
{
|
||
int index = Application.dataPath.LastIndexOf('/');
|
||
var proto_dir = $"{Application.dataPath.Substring(0, index)}/ServerProtos";
|
||
|
||
folder = EditorUtility.OpenFolderPanel("Select proto files source 请选择proto文件路径", proto_dir, "");
|
||
}
|
||
|
||
GUILayout.EndHorizontal();
|
||
|
||
/*
|
||
* 文件
|
||
*/
|
||
GUILayout.Space(10);
|
||
GUILayout.Label("Files to convert 需转换文件");
|
||
//更新
|
||
_serializedObject.Update();
|
||
//开始检查是否有修改
|
||
EditorGUI.BeginChangeCheck();
|
||
//显示属性
|
||
EditorGUILayout.PropertyField(_fileListProperty, true);
|
||
|
||
//结束检查是否有修改
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
//提交修改
|
||
_serializedObject.ApplyModifiedProperties();
|
||
}
|
||
|
||
/*
|
||
* 按钮
|
||
*/
|
||
GUILayout.Space(50);
|
||
if (GUILayout.Button("Match all files from folder 从文件夹中匹配全部文件"))
|
||
{
|
||
_fileList = GetAllProtoFiles(folder);
|
||
_serializedObject.Update();
|
||
}
|
||
|
||
GUILayout.Space(10);
|
||
if (GUILayout.Button("Generate 生成"))
|
||
{
|
||
var dest_folder = $"{Application.dataPath}/Gen/Network";
|
||
//Generate(folder, _fileList, dest_folder);
|
||
}
|
||
}
|
||
|
||
private static string[] GetAllProtoFiles(string path)
|
||
{
|
||
if (string.IsNullOrEmpty(path))
|
||
{
|
||
Debug.LogError($"Folder path is empty!");
|
||
return null;
|
||
}
|
||
|
||
var file_list = Directory.GetFiles(path, "*.proto", SearchOption.AllDirectories);
|
||
var file_name_list = new string[file_list.Length];
|
||
|
||
for (int i = 0; i < file_list.Length; i++)
|
||
{
|
||
file_name_list[i] = Path.GetFileName(file_list[i]);
|
||
}
|
||
|
||
return file_name_list;
|
||
}
|
||
|
||
private static void Generate(string inpath, string[] inprotos, string outpath)
|
||
{
|
||
if (!Directory.Exists(outpath))
|
||
{
|
||
Directory.CreateDirectory(outpath);
|
||
}
|
||
|
||
var set = new FileDescriptorSet();
|
||
set.AddImportPath(inpath);
|
||
foreach (var inproto in inprotos)
|
||
{
|
||
var s = inproto;
|
||
if (!inproto.Contains(".proto"))
|
||
{
|
||
s += ".proto";
|
||
}
|
||
|
||
set.Add(s, true);
|
||
}
|
||
|
||
set.Process();
|
||
var errors = set.GetErrors();
|
||
CSharpCodeGenerator.ClearTypeNames();
|
||
var files = CSharpCodeGenerator.Default.Generate(set);
|
||
|
||
foreach (var file in files)
|
||
{
|
||
CSharpCodeGenerator.ClearTypeNames();
|
||
var full_file_name = file.Name;
|
||
int index = full_file_name.LastIndexOf('.');
|
||
var file_name = index > 0 ? full_file_name.Substring(0, index) : full_file_name;
|
||
file_name = file_name.ToLower();
|
||
var dest_filename = $"{NameNormalizer.AutoCapitalize(file_name)}.cs";
|
||
//var path = Path.Combine(outpath, file.Name);
|
||
var path = Path.Combine(outpath, dest_filename);
|
||
File.WriteAllText(path, file.Text);
|
||
|
||
Debug.Log($"Generated cs file for {full_file_name.Replace(".cs", ".proto")} successfully to: {path}");
|
||
}
|
||
|
||
EditorUtility.DisplayDialog("Complete",
|
||
"Proto文件已转CS,详细请看控制台输出" +
|
||
"\n" +
|
||
"Proto files has been convert into CS files, please go to console and view details",
|
||
"Close window");
|
||
|
||
if (win != null)
|
||
{
|
||
win.Close();
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
}
|
||
|
||
} |