aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server
diff options
context:
space:
mode:
authorMelanie2013-06-23 01:59:57 +0100
committerMelanie2013-06-23 01:59:57 +0100
commitf70357eaa355b8c152f3d793d0fceafa14df5fd4 (patch)
treeffda32c340bd7f6d69652e9d9a959c7396f42a2f /OpenSim/Server
parentMerge branch 'avination-current' into careminster (diff)
parentMerge branch 'master' of melanie@opensimulator.org:/var/git/opensim (diff)
downloadopensim-SC_OLD-f70357eaa355b8c152f3d793d0fceafa14df5fd4.zip
opensim-SC_OLD-f70357eaa355b8c152f3d793d0fceafa14df5fd4.tar.gz
opensim-SC_OLD-f70357eaa355b8c152f3d793d0fceafa14df5fd4.tar.bz2
opensim-SC_OLD-f70357eaa355b8c152f3d793d0fceafa14df5fd4.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Framework/Monitoring/BaseStatsCollector.cs OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
Diffstat (limited to 'OpenSim/Server')
-rw-r--r--OpenSim/Server/Base/ServicesServerBase.cs20
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs2
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs200
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs2
-rw-r--r--OpenSim/Server/Handlers/Simulation/AgentHandlers.cs77
5 files changed, 108 insertions, 193 deletions
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs
index b13c87d..667cef8 100644
--- a/OpenSim/Server/Base/ServicesServerBase.cs
+++ b/OpenSim/Server/Base/ServicesServerBase.cs
@@ -34,6 +34,7 @@ using System.Text;
34using System.Xml; 34using System.Xml;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
37using OpenSim.Framework.Monitoring;
37using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
38using log4net; 39using log4net;
39using log4net.Config; 40using log4net.Config;
@@ -190,16 +191,7 @@ namespace OpenSim.Server.Base
190 } 191 }
191 192
192 RegisterCommonCommands(); 193 RegisterCommonCommands();
193 194 RegisterCommonComponents(Config);
194 // Register the quit command
195 //
196 MainConsole.Instance.Commands.AddCommand("General", false, "quit",
197 "quit",
198 "Quit the application", HandleQuit);
199
200 MainConsole.Instance.Commands.AddCommand("General", false, "shutdown",
201 "shutdown",
202 "Quit the application", HandleQuit);
203 195
204 // Allow derived classes to perform initialization that 196 // Allow derived classes to perform initialization that
205 // needs to be done after the console has opened 197 // needs to be done after the console has opened
@@ -214,6 +206,9 @@ namespace OpenSim.Server.Base
214 206
215 public virtual int Run() 207 public virtual int Run()
216 { 208 {
209 Watchdog.Enabled = true;
210 MemoryWatchdog.Enabled = true;
211
217 while (m_Running) 212 while (m_Running)
218 { 213 {
219 try 214 try
@@ -231,11 +226,12 @@ namespace OpenSim.Server.Base
231 return 0; 226 return 0;
232 } 227 }
233 228
234 protected virtual void HandleQuit(string module, string[] args) 229 protected override void ShutdownSpecific()
235 { 230 {
236 m_Running = false; 231 m_Running = false;
237 m_log.Info("[CONSOLE] Quitting"); 232 m_log.Info("[CONSOLE] Quitting");
238 233
234 base.ShutdownSpecific();
239 } 235 }
240 236
241 protected virtual void ReadConfig() 237 protected virtual void ReadConfig()
@@ -246,4 +242,4 @@ namespace OpenSim.Server.Base
246 { 242 {
247 } 243 }
248 } 244 }
249} 245} \ No newline at end of file
diff --git a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs
index cf1af15..adc2fbc 100644
--- a/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/AgentHandlers.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
61 m_Proxy = proxy; 61 m_Proxy = proxy;
62 } 62 }
63 63
64 protected override bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) 64 protected override bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason)
65 { 65 {
66 return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason); 66 return m_GatekeeperService.LoginAgent(aCircuit, destination, out reason);
67 } 67 }
diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs
index 968c1e6..df875af 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs
@@ -49,191 +49,87 @@ using log4net;
49 49
50namespace OpenSim.Server.Handlers.Hypergrid 50namespace OpenSim.Server.Handlers.Hypergrid
51{ 51{
52 public class HomeAgentHandler 52 public class HomeAgentHandler : AgentPostHandler
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private IUserAgentService m_UserAgentService; 55 private IUserAgentService m_UserAgentService;
56 56
57 private string m_LoginServerIP; 57 private string m_LoginServerIP;
58 private bool m_Proxy = false;
59 58
60 public HomeAgentHandler(IUserAgentService userAgentService, string loginServerIP, bool proxy) 59 public HomeAgentHandler(IUserAgentService userAgentService, string loginServerIP, bool proxy) :
60 base("/homeagent")
61 { 61 {
62 m_UserAgentService = userAgentService; 62 m_UserAgentService = userAgentService;
63 m_LoginServerIP = loginServerIP; 63 m_LoginServerIP = loginServerIP;
64 m_Proxy = proxy; 64 m_Proxy = proxy;
65 } 65 }
66 66
67 public Hashtable Handler(Hashtable request) 67 protected override AgentDestinationData CreateAgentDestinationData()
68 { 68 {
69// m_log.Debug("[CONNECTION DEBUGGING]: HomeAgentHandler Called"); 69 return new ExtendedAgentDestinationData();
70// 70 }
71// m_log.Debug("---------------------------"); 71 protected override void UnpackData(OSDMap args, AgentDestinationData d, Hashtable request)
72// m_log.Debug(" >> uri=" + request["uri"]); 72 {
73// m_log.Debug(" >> content-type=" + request["content-type"]); 73 base.UnpackData(args, d, request);
74// m_log.Debug(" >> http-method=" + request["http-method"]); 74 ExtendedAgentDestinationData data = (ExtendedAgentDestinationData)d;
75// m_log.Debug("---------------------------\n"); 75 try
76
77 Hashtable responsedata = new Hashtable();
78 responsedata["content_type"] = "text/html";
79 responsedata["keepalive"] = false;
80
81
82 UUID agentID;
83 UUID regionID;
84 string action;
85 if (!Utils.GetParams((string)request["uri"], out agentID, out regionID, out action))
86 { 76 {
87 m_log.InfoFormat("[HOME AGENT HANDLER]: Invalid parameters for agent message {0}", request["uri"]); 77 if (args.ContainsKey("gatekeeper_host") && args["gatekeeper_host"] != null)
88 responsedata["int_response_code"] = 404; 78 data.host = args["gatekeeper_host"].AsString();
89 responsedata["str_response_string"] = "false"; 79 if (args.ContainsKey("gatekeeper_port") && args["gatekeeper_port"] != null)
80 Int32.TryParse(args["gatekeeper_port"].AsString(), out data.port);
81 if (args.ContainsKey("gatekeeper_serveruri") && args["gatekeeper_serveruri"] != null)
82 data.gatekeeperServerURI = args["gatekeeper_serveruri"];
83 if (args.ContainsKey("destination_serveruri") && args["destination_serveruri"] != null)
84 data.destinationServerURI = args["destination_serveruri"];
90 85
91 return responsedata;
92 } 86 }
93 87 catch (InvalidCastException e)
94 // Next, let's parse the verb
95 string method = (string)request["http-method"];
96 if (method.Equals("POST"))
97 { 88 {
98 DoAgentPost(request, responsedata, agentID); 89 m_log.ErrorFormat("[HOME AGENT HANDLER]: Bad cast in UnpackData");
99 return responsedata;
100 } 90 }
101 else
102 {
103 m_log.InfoFormat("[HOME AGENT HANDLER]: method {0} not supported in agent message", method);
104 responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed;
105 responsedata["str_response_string"] = "Method not allowed";
106 91
107 return responsedata; 92 string callerIP = GetCallerIP(request);
108 } 93 // Verify if this call came from the login server
94 if (callerIP == m_LoginServerIP)
95 data.fromLogin = true;
109 96
110 } 97 }
111 98
112 protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) 99 protected override GridRegion ExtractGatekeeper(AgentDestinationData d)
113 { 100 {
114 OSDMap args = Utils.GetOSDMap((string)request["body"]); 101 if (d is ExtendedAgentDestinationData)
115 if (args == null)
116 { 102 {
117 responsedata["int_response_code"] = HttpStatusCode.BadRequest; 103 ExtendedAgentDestinationData data = (ExtendedAgentDestinationData)d;
118 responsedata["str_response_string"] = "Bad request"; 104 GridRegion gatekeeper = new GridRegion();
119 return; 105 gatekeeper.ServerURI = data.gatekeeperServerURI;
106 gatekeeper.ExternalHostName = data.host;
107 gatekeeper.HttpPort = (uint)data.port;
108 gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
109
110 return gatekeeper;
120 } 111 }
121
122 // retrieve the input arguments
123 int x = 0, y = 0;
124 UUID uuid = UUID.Zero;
125 string regionname = string.Empty;
126 string gatekeeper_host = string.Empty;
127 string gatekeeper_serveruri = string.Empty;
128 string destination_serveruri = string.Empty;
129 int gatekeeper_port = 0;
130 IPEndPoint client_ipaddress = null;
131
132 if (args.ContainsKey("gatekeeper_host") && args["gatekeeper_host"] != null)
133 gatekeeper_host = args["gatekeeper_host"].AsString();
134 if (args.ContainsKey("gatekeeper_port") && args["gatekeeper_port"] != null)
135 Int32.TryParse(args["gatekeeper_port"].AsString(), out gatekeeper_port);
136 if (args.ContainsKey("gatekeeper_serveruri") && args["gatekeeper_serveruri"] !=null)
137 gatekeeper_serveruri = args["gatekeeper_serveruri"];
138 if (args.ContainsKey("destination_serveruri") && args["destination_serveruri"] !=null)
139 destination_serveruri = args["destination_serveruri"];
140
141 GridRegion gatekeeper = new GridRegion();
142 gatekeeper.ServerURI = gatekeeper_serveruri;
143 gatekeeper.ExternalHostName = gatekeeper_host;
144 gatekeeper.HttpPort = (uint)gatekeeper_port;
145 gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
146
147 if (args.ContainsKey("destination_x") && args["destination_x"] != null)
148 Int32.TryParse(args["destination_x"].AsString(), out x);
149 else 112 else
150 m_log.WarnFormat(" -- request didn't have destination_x"); 113 m_log.WarnFormat("[HOME AGENT HANDLER]: Wrong data type");
151 if (args.ContainsKey("destination_y") && args["destination_y"] != null)
152 Int32.TryParse(args["destination_y"].AsString(), out y);
153 else
154 m_log.WarnFormat(" -- request didn't have destination_y");
155 if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null)
156 UUID.TryParse(args["destination_uuid"].AsString(), out uuid);
157 if (args.ContainsKey("destination_name") && args["destination_name"] != null)
158 regionname = args["destination_name"].ToString();
159
160 if (args.ContainsKey("client_ip") && args["client_ip"] != null)
161 {
162 string ip_str = args["client_ip"].ToString();
163 try
164 {
165 string callerIP = GetCallerIP(request);
166 // Verify if this caller has authority to send the client IP
167 if (callerIP == m_LoginServerIP)
168 client_ipaddress = new IPEndPoint(IPAddress.Parse(ip_str), 0);
169 else // leaving this for now, but this warning should be removed
170 m_log.WarnFormat("[HOME AGENT HANDLER]: Unauthorized machine {0} tried to set client ip to {1}", callerIP, ip_str);
171 }
172 catch
173 {
174 m_log.DebugFormat("[HOME AGENT HANDLER]: Exception parsing client ip address from {0}", ip_str);
175 }
176 }
177
178 GridRegion destination = new GridRegion();
179 destination.RegionID = uuid;
180 destination.RegionLocX = x;
181 destination.RegionLocY = y;
182 destination.RegionName = regionname;
183 destination.ServerURI = destination_serveruri;
184
185 AgentCircuitData aCircuit = new AgentCircuitData();
186 try
187 {
188 aCircuit.UnpackAgentCircuitData(args);
189 }
190 catch (Exception ex)
191 {
192 m_log.InfoFormat("[HOME AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message);
193 responsedata["int_response_code"] = HttpStatusCode.BadRequest;
194 responsedata["str_response_string"] = "Bad request";
195 return;
196 }
197
198 OSDMap resp = new OSDMap(2);
199 string reason = String.Empty;
200 114
201 bool result = m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, client_ipaddress, out reason); 115 return null;
202
203 resp["reason"] = OSD.FromString(reason);
204 resp["success"] = OSD.FromBoolean(result);
205
206 // TODO: add reason if not String.Empty?
207 responsedata["int_response_code"] = HttpStatusCode.OK;
208 responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
209 } 116 }
210 117
211 private string GetCallerIP(Hashtable request)
212 {
213 if (!m_Proxy)
214 return Util.GetCallerIP(request);
215
216 // We're behind a proxy
217 Hashtable headers = (Hashtable)request["headers"];
218 string xff = "X-Forwarded-For";
219 if (headers.ContainsKey(xff.ToLower()))
220 xff = xff.ToLower();
221 118
222 if (!headers.ContainsKey(xff) || headers[xff] == null) 119 protected override bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason)
223 { 120 {
224 m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); 121 return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, fromLogin, out reason);
225 return Util.GetCallerIP(request); 122 }
226 }
227 123
228 m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); 124 }
229 125
230 IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); 126 public class ExtendedAgentDestinationData : AgentDestinationData
231 if (ep != null) 127 {
232 return ep.Address.ToString(); 128 public string host;
129 public int port;
130 public string gatekeeperServerURI;
131 public string destinationServerURI;
233 132
234 // Oops
235 return Util.GetCallerIP(request);
236 }
237 } 133 }
238 134
239} 135}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index b20f467..d9c1bd3 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -108,7 +108,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
108 server.AddXmlRPCHandler("get_uui", GetUUI, false); 108 server.AddXmlRPCHandler("get_uui", GetUUI, false);
109 server.AddXmlRPCHandler("get_uuid", GetUUID, false); 109 server.AddXmlRPCHandler("get_uuid", GetUUID, false);
110 110
111 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); 111 server.AddStreamHandler(new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy));
112 } 112 }
113 113
114 public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient) 114 public XmlRpcResponse GetHomeRegion(XmlRpcRequest request, IPEndPoint remoteClient)
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
index 9b34298..c62f256 100644
--- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
@@ -351,31 +351,16 @@ namespace OpenSim.Server.Handlers.Simulation
351 return; 351 return;
352 } 352 }
353 353
354 // retrieve the input arguments 354 AgentDestinationData data = CreateAgentDestinationData();
355 int x = 0, y = 0; 355 UnpackData(args, data, request);
356 UUID uuid = UUID.Zero;
357 string regionname = string.Empty;
358 uint teleportFlags = 0;
359 if (args.ContainsKey("destination_x") && args["destination_x"] != null)
360 Int32.TryParse(args["destination_x"].AsString(), out x);
361 else
362 m_log.WarnFormat(" -- request didn't have destination_x");
363 if (args.ContainsKey("destination_y") && args["destination_y"] != null)
364 Int32.TryParse(args["destination_y"].AsString(), out y);
365 else
366 m_log.WarnFormat(" -- request didn't have destination_y");
367 if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null)
368 UUID.TryParse(args["destination_uuid"].AsString(), out uuid);
369 if (args.ContainsKey("destination_name") && args["destination_name"] != null)
370 regionname = args["destination_name"].ToString();
371 if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null)
372 teleportFlags = args["teleport_flags"].AsUInteger();
373 356
374 GridRegion destination = new GridRegion(); 357 GridRegion destination = new GridRegion();
375 destination.RegionID = uuid; 358 destination.RegionID = data.uuid;
376 destination.RegionLocX = x; 359 destination.RegionLocX = data.x;
377 destination.RegionLocY = y; 360 destination.RegionLocY = data.y;
378 destination.RegionName = regionname; 361 destination.RegionName = data.name;
362
363 GridRegion gatekeeper = ExtractGatekeeper(data);
379 364
380 AgentCircuitData aCircuit = new AgentCircuitData(); 365 AgentCircuitData aCircuit = new AgentCircuitData();
381 try 366 try
@@ -396,7 +381,7 @@ namespace OpenSim.Server.Handlers.Simulation
396 // This is the meaning of POST agent 381 // This is the meaning of POST agent
397 //m_regionClient.AdjustUserInformation(aCircuit); 382 //m_regionClient.AdjustUserInformation(aCircuit);
398 //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); 383 //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason);
399 bool result = CreateAgent(destination, aCircuit, teleportFlags, out reason); 384 bool result = CreateAgent(gatekeeper, destination, aCircuit, data.flags, data.fromLogin, out reason);
400 385
401 resp["reason"] = OSD.FromString(reason); 386 resp["reason"] = OSD.FromString(reason);
402 resp["success"] = OSD.FromBoolean(result); 387 resp["success"] = OSD.FromBoolean(result);
@@ -408,7 +393,36 @@ namespace OpenSim.Server.Handlers.Simulation
408 responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); 393 responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
409 } 394 }
410 395
411 private string GetCallerIP(Hashtable request) 396 protected virtual AgentDestinationData CreateAgentDestinationData()
397 {
398 return new AgentDestinationData();
399 }
400
401 protected virtual void UnpackData(OSDMap args, AgentDestinationData data, Hashtable request)
402 {
403 // retrieve the input arguments
404 if (args.ContainsKey("destination_x") && args["destination_x"] != null)
405 Int32.TryParse(args["destination_x"].AsString(), out data.x);
406 else
407 m_log.WarnFormat(" -- request didn't have destination_x");
408 if (args.ContainsKey("destination_y") && args["destination_y"] != null)
409 Int32.TryParse(args["destination_y"].AsString(), out data.y);
410 else
411 m_log.WarnFormat(" -- request didn't have destination_y");
412 if (args.ContainsKey("destination_uuid") && args["destination_uuid"] != null)
413 UUID.TryParse(args["destination_uuid"].AsString(), out data.uuid);
414 if (args.ContainsKey("destination_name") && args["destination_name"] != null)
415 data.name = args["destination_name"].ToString();
416 if (args.ContainsKey("teleport_flags") && args["teleport_flags"] != null)
417 data.flags = args["teleport_flags"].AsUInteger();
418 }
419
420 protected virtual GridRegion ExtractGatekeeper(AgentDestinationData data)
421 {
422 return null;
423 }
424
425 protected string GetCallerIP(Hashtable request)
412 { 426 {
413 if (!m_Proxy) 427 if (!m_Proxy)
414 return Util.GetCallerIP(request); 428 return Util.GetCallerIP(request);
@@ -441,7 +455,7 @@ namespace OpenSim.Server.Handlers.Simulation
441 } 455 }
442 456
443 // subclasses can override this 457 // subclasses can override this
444 protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) 458 protected virtual bool CreateAgent(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, out string reason)
445 { 459 {
446 reason = String.Empty; 460 reason = String.Empty;
447 461
@@ -593,7 +607,6 @@ namespace OpenSim.Server.Handlers.Simulation
593 //agent.Dump(); 607 //agent.Dump();
594 // This is one of the meanings of PUT agent 608 // This is one of the meanings of PUT agent
595 result = UpdateAgent(destination, agent); 609 result = UpdateAgent(destination, agent);
596
597 } 610 }
598 else if ("AgentPosition".Equals(messageType)) 611 else if ("AgentPosition".Equals(messageType))
599 { 612 {
@@ -624,4 +637,14 @@ namespace OpenSim.Server.Handlers.Simulation
624 return m_SimulationService.UpdateAgent(destination, agent); 637 return m_SimulationService.UpdateAgent(destination, agent);
625 } 638 }
626 } 639 }
640
641 public class AgentDestinationData
642 {
643 public int x;
644 public int y;
645 public string name;
646 public UUID uuid;
647 public uint flags;
648 public bool fromLogin;
649 }
627} 650}