UH3L12——工具窗口逻辑处理

前置知识点

  • UH3L3——生成AB包资源对比文件
  • UH3L4——上传AB包和信息文件
  • UH3L8——编辑器功能—设置默认资源

目标

将之前的编辑器功能整合到上节课创建的窗口中

将之前编写的静态方法移植到窗口类,然后在对应的按钮代码块里调用即可,但是需要进行如下的修改:

  • 将静态方法改为私有方法
  • UploadABFile​内,读取文件夹的路径需要根据平台页签的选择而动态改变
  • FtpUploadFile​内,服务器的上传路径需要根据窗口输入的IP以及平台页签的选择而动态改变
  • CreateABCompareFile​,读取文件夹和生成文件夹的路径需要根据平台页签的选择而动态改变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;

public class ABTools : EditorWindow
{
private int nowSelIndex = 0;
private string[] targetStrings = new string[] { "PC", "IOS", "Android" };
private string serverIP = "ftp://192.168.1.101";

[MenuItem("AB包工具/打开工具窗口")]
private static void OpenWindow()
{
ABTools window = EditorWindow.GetWindowWithRect<ABTools>(new Rect(0, 0, 350, 220));
window.Show();
}

private void OnGUI()
{
GUI.Label(new Rect(10, 10, 150, 15), "平台选择");
//页签显示 是从数组中取出字符串内容来显示,所以需要改变当前选中的索引
nowSelIndex = GUI.Toolbar(new Rect(10, 30, 330, 20), nowSelIndex, targetStrings);
//资源服务器IP地址设置
GUI.Label(new Rect(10, 60, 150, 15), "资源服务器地址");
serverIP = GUI.TextField(new Rect(10, 80, 330, 20), serverIP);
//创建对比文件 按钮
if (GUI.Button(new Rect(10, 110, 100, 40), "创建对比文件"))
CreateABCompareFile();
//保存默认资源到StreamingAssets按钮
if (GUI.Button(new Rect(115, 110, 225, 40), "保存默认资源到StreamingAssets"))
MoveABToStreamingAssets();
//上传AB包和对比文件按钮
if (GUI.Button(new Rect(10, 160, 330, 40), "上传AB包和对比文件"))
UploadABFile();
}

private void UploadABFile()
{
DirectoryInfo directory = new DirectoryInfo(Application.dataPath + $"/ArtRes/AB/{targetStrings[nowSelIndex]}/");
FileInfo[] fileInfos = directory.GetFiles();

foreach (FileInfo info in fileInfos)
{
//检查后缀,没有后缀的是AB包,txt后缀的是资源对比文件,这两个才是需要上传的内容
if (info.Extension == "" ||
info.Extension == ".txt")
{
//上传该文件
FtpUploadFile(info.FullName, info.Name);
}
}
}

private async void FtpUploadFile(string filePath, string fileName)
{
await Task.Run(() =>
{
try
{
//创建一个FTP连接 用于上传
FtpWebRequest request = FtpWebRequest.Create(new System.Uri($"{serverIP}/AB/{targetStrings[nowSelIndex]}/" + fileName)) as FtpWebRequest;
//设置通信凭证
NetworkCredential credential = new NetworkCredential("MrTang", "MrTang123");
request.Credentials = credential;
//其他设置:代理设置为null,请求完毕后关闭控制连接,操作命令设置为上传,指定传输二进制类型数据
request.Proxy = null;
request.KeepAlive = false;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
//获取上传流
Stream upLoadStream = request.GetRequestStream();
//获取读取文件的流
using (FileStream file = File.OpenRead(filePath))
{
//使用字节数组一点一点的从文件里读取内容,并写入到文件流内
byte[] bytes = new byte[2048];
int contentLength = file.Read(bytes, 0, bytes.Length);
while (contentLength > 0)
{
upLoadStream.Write(bytes, 0, contentLength);
contentLength = file.Read(bytes, 0, bytes.Length);
}
file.Close();
upLoadStream.Close();
}
Debug.Log($"{fileName}上传成功");
}
catch (System.Exception e)
{
Debug.Log($"{fileName}上传失败:{e.Message}");
}
});
}

//将选中的资源移动到StreamingAssets文件夹中
private void MoveABToStreamingAssets()
{
//通过编辑器Selection类中的方法,获取在Project窗口选中的资源
Object[] selectedAsset = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.DeepAssets);
if (selectedAsset.Length == 0)
return;
//用于拼接本地默认AB包资源消息的字符串
string abCompareInfo = "";
//遍历选中的资源对象
foreach (Object asset in selectedAsset)
{
//通过AssetDatabase类获取资源的路径
string assetPath = AssetDatabase.GetAssetPath(asset);
//截取路径当中的文件名,用于作为StreamingAsset中的文件名
string fileName = assetPath.Substring(assetPath.LastIndexOf('/'));
//如果文件名有'.',说明有后缀名,也就不是AB包,因此我们需要忽略掉
if (fileName.IndexOf('.') != -1)
continue;
//利用AssetDatabase中的API将选中文件复制到目标路径
AssetDatabase.CopyAsset(assetPath, "Assets/StreamingAssets" + fileName);
//获取拷贝到StreamingAssets文件夹中的文件的全部信息
FileInfo fileInfo = new FileInfo(Application.streamingAssetsPath + fileName);
abCompareInfo += fileInfo.Name + " " + fileInfo.Length + " " + CreateABCompare.GetMD5(fileInfo.FullName);
abCompareInfo += "|";
}
//去掉最后一个|符号,为了之后拆分字符串方便
abCompareInfo = abCompareInfo.Substring(0, abCompareInfo.Length - 1);
//将本地默认资源的对比消息存入文件
File.WriteAllText(Application.streamingAssetsPath + "/ABCompareInfo.txt", abCompareInfo);
AssetDatabase.Refresh();
}

// 生成AB包对比文件
private void CreateABCompareFile()
{
//要根据选择的平台读取对应平台的文件夹下的内容,来进行对比文件的生成
DirectoryInfo directory = new DirectoryInfo(Application.dataPath + $"/ArtRes/AB/{targetStrings[nowSelIndex]}");
FileInfo[] fileInfos = directory.GetFiles();
string abCompareInfo = "";
foreach (FileInfo info in fileInfos)
{
//检查后缀,没有后缀的,才是AB包,我们只需要AB包的消息
if (info.Extension == "")
{
//拼接一个AB包的消息
abCompareInfo += info.Name + " " + info.Length + " " + GetMD5(info.FullName);
//用分隔符分开不同文件之间的消息
abCompareInfo += "|";
}
}
//删除最后一个"|"
abCompareInfo = abCompareInfo.Substring(0, abCompareInfo.Length - 1);
File.WriteAllText(Application.dataPath + $"/ArtRes/AB/{targetStrings[nowSelIndex]}/ABCompareInfo.txt", abCompareInfo);
Debug.Log("AB包对比文件生成完毕!");
AssetDatabase.Refresh(); //刷新编辑器
}

//获取文件MD5码
private string GetMD5(string filePath)
{
using (FileStream file = new FileStream(filePath, FileMode.Open))
{
//声明一个MD5对象,用于生成MD5码
MD5 md5 = new MD5CryptoServiceProvider();
//利用API得到数据的MD5码 16个字节的数组
byte[] md5Info = md5.ComputeHash(file);
//把16个字节转换为16进制 拼接成字符串,为了减小md5码的长度
StringBuilder sb = new StringBuilder();
file.Close();
for (int i = 0; i < md5Info.Length; i++)
//关于md5Info[i].ToString()内的参数,如果传入X2就是大写的16进制,x2就是小写的
sb.Append(md5Info[i].ToString("x2"));
return sb.ToString();
}
}
}