Skip to content

Commit f3a5108

Browse files
unknownunknown
authored andcommitted
init
1 parent e5ee8f2 commit f3a5108

17 files changed

Lines changed: 426 additions & 0 deletions

MaxServer.cs

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.Concurrent;
4+
using System.Diagnostics;
5+
using System.Linq;
6+
using System.Net;
7+
using System.Web;
8+
using System.Text;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
using System.Windows.Threading;
12+
using System.Net.Sockets;
13+
14+
/// 加载Autodesk DLLs
15+
using Autodesk.Max;
16+
using UiViewModels.Actions;
17+
18+
namespace MaxServer
19+
{
20+
/// <summary>
21+
/// 3dmax .NET实现web服务
22+
/// </summary>
23+
public class MaxServer : CuiActionCommandAdapter
24+
{
25+
/// <summary>
26+
/// web服务器监听,主线程执行代码
27+
/// </summary>
28+
static Dispatcher dispatcher;
29+
/// <summary>
30+
/// 指定监听端口
31+
/// </summary>
32+
static string port = "8080";
33+
/// static string host = "192.168.150.133";
34+
/// <summary>
35+
/// http服务
36+
/// </summary>
37+
HttpListener listener;
38+
39+
/// <summary>
40+
/// 关联 3ds Max .NET API
41+
/// </summary>
42+
IGlobal global;
43+
44+
/// <summary>
45+
/// 获取post提交的数据,返回解析数据
46+
/// </summary>
47+
public static string GetFormData(HttpListenerRequest request, string formName)
48+
{
49+
if (request == null || !request.HasEntityBody)
50+
return "";
51+
var body = request.InputStream;
52+
var encoding = request.ContentEncoding;
53+
var reader = new System.IO.StreamReader(body, encoding);
54+
var text = reader.ReadToEnd();
55+
body.Close();
56+
reader.Close();
57+
var queryVars = HttpUtility.ParseQueryString(text, encoding);
58+
return queryVars[formName];
59+
}
60+
61+
/// <summary>
62+
/// 循环处理web请求
63+
/// </summary>
64+
public void ListenLoop()
65+
{
66+
try
67+
{
68+
while (listener.IsListening)
69+
{
70+
var context = listener.GetContext();
71+
var request = context.Request;
72+
var url = request.Url;
73+
74+
//判断是否是服务终止请求
75+
if (url.PathAndQuery == "/exit")
76+
{
77+
string res = BuildResponseText(200, "success", "stop");
78+
WriteResponse(context, res);
79+
listener.Stop();
80+
}
81+
else if (context != null && listener.IsListening)
82+
{
83+
if (url.PathAndQuery == "/healthz")
84+
{
85+
string res = BuildResponseText(200, "success", "healthy");
86+
WriteResponse(context, res);
87+
}
88+
else
89+
{
90+
//获取请求文本(maxscript code)
91+
//var code = GetFormData(request, "code");
92+
var body = request.InputStream;
93+
var encoding = request.ContentEncoding;
94+
var reader = new System.IO.StreamReader(body, encoding);
95+
var text = reader.ReadToEnd();
96+
body.Close();
97+
reader.Close();
98+
var queryVars = HttpUtility.ParseQueryString(text, encoding);
99+
//
100+
var maxcode = queryVars["maxcode"];
101+
var esspath = queryVars["esspath"];
102+
// 执行maxscript code
103+
Action a = () => global.ExecuteMAXScriptScript(maxcode, false, null);
104+
dispatcher.Invoke(a);
105+
//执行完返回信息
106+
string res = BuildResponseText(200, "success", esspath);
107+
WriteResponse(context, res);
108+
}
109+
}
110+
}
111+
}
112+
catch (Exception e)
113+
{
114+
Debug.WriteLine(e.Message);
115+
}
116+
}
117+
118+
/// <summary>
119+
/// 构造响应信息结构
120+
/// </summary>
121+
public string BuildResponseText(int errcode, string msg, string data)
122+
{
123+
string strErrCode = errcode.ToString();
124+
string res = "{\"errcode\":" + strErrCode + "," +
125+
"\"msg\":" + "\"" + msg + "\"" + "," +
126+
"\"data\":{" +
127+
"\"res\":" + "\"" +data + "\"" + "}}";
128+
return res;
129+
}
130+
131+
/// <summary>
132+
/// 发送响应信息到客户端
133+
/// </summary>
134+
public void WriteResponse(HttpListenerContext context, string s)
135+
{
136+
WriteResponse(context.Response, s);
137+
}
138+
139+
/// <summary>
140+
/// 发送响应信息到客户端
141+
/// </summary>
142+
public void WriteResponse(HttpListenerResponse response, string s)
143+
{
144+
response.AddHeader("Access-Control-Allow-Origin", "*");
145+
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(s);
146+
response.ContentLength64 = buffer.Length;
147+
System.IO.Stream output = response.OutputStream;
148+
output.Write(buffer, 0, buffer.Length);
149+
output.Close();
150+
}
151+
152+
/// <summary>
153+
///设置web服务器,执行maxscript code
154+
/// </summary>
155+
public override void Execute(object param)
156+
{
157+
if (param != null && param.ToString() != "") {
158+
port = param.ToString();
159+
}
160+
161+
try
162+
{
163+
if (listener != null)
164+
return;
165+
166+
dispatcher = Dispatcher.CurrentDispatcher;
167+
global = Autodesk.Max.GlobalInterface.Instance;
168+
listener = new HttpListener();
169+
170+
if (!HttpListener.IsSupported)
171+
{
172+
WriteLine("HTTP Listener is not supported on this platform.");
173+
return;
174+
}
175+
176+
// 设置监听规则
177+
// listener.Prefixes.Add("http://*:"+ port + "/");
178+
listener.Prefixes.Add("http://127.0.0.1:"+ port + "/");
179+
listener.Prefixes.Add("http://localhost:"+ port + "/");
180+
listener.Prefixes.Add("http://" + GetLocalIP() + ":" + port + "/");
181+
try
182+
{
183+
WriteLine("Starting HTTP listener");
184+
listener.Start();
185+
WriteLine("HTTP listener started");
186+
}
187+
catch (HttpListenerException he)
188+
{
189+
WriteLine("Unable to start the HTTP listener service. Try running 3ds Max in administrator mode. " + he.Message);
190+
}
191+
192+
WriteLine("Launching new thread");
193+
var t = new Thread(() => ListenLoop());
194+
t.Start();
195+
}
196+
catch (Exception e)
197+
{
198+
WriteLine(e.Message);
199+
}
200+
}
201+
202+
/// <summary>
203+
/// 与用户操作关联的字符串
204+
/// </summary>
205+
public override string ActionText
206+
{
207+
get { return "MAXScript web server"; }
208+
}
209+
210+
/// <summary>
211+
/// 与用户操作相关联的类别。这在定制用户界面时显示。
212+
/// </summary>
213+
public override string Category
214+
{
215+
get { return ".NET Samples"; }
216+
}
217+
218+
/// <summary>
219+
/// 与用户操作相关联的字符串,非本地化。
220+
/// </summary>
221+
public override string InternalActionText
222+
{
223+
get { return ActionText; }
224+
}
225+
226+
/// <summary>
227+
/// 类别名称
228+
/// </summary>
229+
public override string InternalCategory
230+
{
231+
get { return Category; }
232+
}
233+
234+
/// <summary>
235+
/// 将文本打印到MAXScript侦听器窗口。
236+
/// </summary>
237+
public void Write(string s)
238+
{
239+
global.TheListener.EditStream.Wputs(s);
240+
global.TheListener.EditStream.Flush();
241+
}
242+
243+
/// <summary>
244+
/// 打印文本到MAXScript listerner窗口。
245+
/// </summary>
246+
public void WriteLine(string s)
247+
{
248+
Write(s + "\n");
249+
}
250+
251+
/// <summary>
252+
/// 获取本机IP(V4)
253+
/// </summary>
254+
public static string GetLocalIP()
255+
{
256+
try
257+
{
258+
string HostName = Dns.GetHostName(); //得到主机名
259+
IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
260+
for (int i = 0; i < IpEntry.AddressList.Length; i++)
261+
{
262+
//从IP地址列表中筛选出IPv4类型的IP地址
263+
//AddressFamily.InterNetwork表示此IP为IPv4,
264+
//AddressFamily.InterNetworkV6表示此地址为IPv6类型
265+
if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
266+
{
267+
return IpEntry.AddressList[i].ToString();
268+
}
269+
}
270+
return "";
271+
}
272+
catch (Exception ex)
273+
{
274+
System.Windows.Forms.MessageBox.Show("获取本机IP出错:" + ex.Message);
275+
return "";
276+
}
277+
}
278+
}
279+
}
280+

MaxServer.csproj

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProductVersion>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{395EA371-F356-4F7B-AAC0-8DAF5B6AEE47}</ProjectGuid>
9+
<OutputType>Library</OutputType>
10+
<AppDesignerFolder>Properties</AppDesignerFolder>
11+
<RootNamespace>MaxServer</RootNamespace>
12+
<AssemblyName>MaxServer</AssemblyName>
13+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14+
<FileAlignment>512</FileAlignment>
15+
<TargetFrameworkProfile>
16+
</TargetFrameworkProfile>
17+
</PropertyGroup>
18+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19+
<DebugSymbols>true</DebugSymbols>
20+
<DebugType>full</DebugType>
21+
<Optimize>false</Optimize>
22+
<OutputPath>..\Program Files\Autodesk\3ds Max 2014\bin\assemblies\</OutputPath>
23+
<DefineConstants>DEBUG;TRACE</DefineConstants>
24+
<ErrorReport>prompt</ErrorReport>
25+
<WarningLevel>4</WarningLevel>
26+
</PropertyGroup>
27+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>..\Program Files\Autodesk\3ds Max 2014\bin\assemblies\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<Reference Include="Autodesk.Max">
37+
<HintPath>..\Program Files\Autodesk\3ds Max 2014\Autodesk.Max.dll</HintPath>
38+
</Reference>
39+
<Reference Include="PresentationCore" />
40+
<Reference Include="System" />
41+
<Reference Include="System.Core" />
42+
<Reference Include="System.Web" />
43+
<Reference Include="System.Windows.Forms" />
44+
<Reference Include="System.Xml.Linq" />
45+
<Reference Include="System.Data.DataSetExtensions" />
46+
<Reference Include="Microsoft.CSharp" />
47+
<Reference Include="System.Data" />
48+
<Reference Include="System.Xml" />
49+
<Reference Include="UiViewModels">
50+
<HintPath>..\Program Files\Autodesk\3ds Max 2014\UiViewModels.dll</HintPath>
51+
</Reference>
52+
<Reference Include="WindowsBase" />
53+
</ItemGroup>
54+
<ItemGroup>
55+
<Compile Include="MaxServer.cs" />
56+
<Compile Include="Properties\AssemblyInfo.cs" />
57+
</ItemGroup>
58+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
59+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
60+
Other similar extension points exist, see Microsoft.Common.targets.
61+
<Target Name="BeforeBuild">
62+
</Target>
63+
<Target Name="AfterBuild">
64+
</Target>
65+
-->
66+
</Project>

MaxServer.csproj.user

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
4+
<StartAction>Program</StartAction>
5+
<StartProgram>D:\Program Files\Autodesk\3ds Max 2014\3dsmax.exe</StartProgram>
6+
</PropertyGroup>
7+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
8+
<StartAction>Program</StartAction>
9+
<StartProgram>D:\Program Files\Autodesk\3ds Max 2014\3dsmax.exe</StartProgram>
10+
</PropertyGroup>
11+
</Project>

MaxServer.sln

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 11.00
3+
# Visual Studio 2010
4+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaxServer", "MaxServer.csproj", "{395EA371-F356-4F7B-AAC0-8DAF5B6AEE47}"
5+
EndProject
6+
Global
7+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8+
Debug|Any CPU = Debug|Any CPU
9+
Release|Any CPU = Release|Any CPU
10+
EndGlobalSection
11+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
12+
{395EA371-F356-4F7B-AAC0-8DAF5B6AEE47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13+
{395EA371-F356-4F7B-AAC0-8DAF5B6AEE47}.Debug|Any CPU.Build.0 = Debug|Any CPU
14+
{395EA371-F356-4F7B-AAC0-8DAF5B6AEE47}.Release|Any CPU.ActiveCfg = Release|Any CPU
15+
{395EA371-F356-4F7B-AAC0-8DAF5B6AEE47}.Release|Any CPU.Build.0 = Release|Any CPU
16+
EndGlobalSection
17+
GlobalSection(SolutionProperties) = preSolution
18+
HideSolutionNode = FALSE
19+
EndGlobalSection
20+
EndGlobal

MaxServer.suo

18 KB
Binary file not shown.

0 commit comments

Comments
 (0)