upm_guru_kcp/Editor/Proto2CSEditor.cs

248 lines
8.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//
// 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();
}
}
}