Compare commits

..

1 Commits

Author SHA1 Message Date
UbitUmarov 45b8697085 0.9.1.1 release and still Snail 2020-01-07 15:03:19 +00:00
392 changed files with 25018 additions and 25971 deletions

View File

@ -252,7 +252,7 @@ namespace OpenSim.Groups
m_debugEnabled = verbose;
MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled);
MainConsole.Instance.Output("{0} verbose logging set to {1}", null, Name, m_debugEnabled);
}
/// <summary>
@ -599,34 +599,36 @@ namespace OpenSim.Groups
{
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
UUID fromAgent = new UUID(msg.fromAgentID);
// Force? open the group session dialog???
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
if (eq != null)
{
eq.ChatterboxInvitation(
GroupID
, groupInfo.GroupName
, fromAgent
, msg.message
, AgentID
, msg.fromAgentName
, msg.dialog
, msg.timestamp
, msg.offline == 1
, (int)msg.ParentEstateID
, msg.Position
, 1
, new UUID(msg.imSessionID)
, msg.fromGroup
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
);
eq.ChatterboxInvitation(
GroupID
, groupInfo.GroupName
, new UUID(msg.fromAgentID)
, msg.message
, AgentID
, msg.fromAgentName
, msg.dialog
, msg.timestamp
, msg.offline == 1
, (int)msg.ParentEstateID
, msg.Position
, 1
, new UUID(msg.imSessionID)
, msg.fromGroup
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
);
var update = new GroupChatListAgentUpdateData(AgentID);
var updates = new List<GroupChatListAgentUpdateData> { update };
eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates);
}
eq.ChatterBoxSessionAgentListUpdates(
new UUID(GroupID)
, AgentID
, new UUID(msg.toAgentID)
, false //canVoiceChat
, false //isModerator
, false //text mute
, true // Enter
);
}
}
}
@ -661,12 +663,15 @@ namespace OpenSim.Groups
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
if (queue != null)
{
var update = new GroupChatListAgentUpdateData(AgentID);
var updates = new List<GroupChatListAgentUpdateData> { update };
queue.ChatterBoxSessionAgentListUpdates(GroupID, remoteClient.AgentId, updates);
}
queue.ChatterBoxSessionAgentListUpdates(
GroupID
, AgentID
, new UUID(im.toAgentID)
, false //canVoiceChat
, false //isModerator
, false //text mute
, true
);
}
}
@ -708,7 +713,11 @@ namespace OpenSim.Groups
bodyMap.Add("session_info", sessionMap);
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
if (queue != null)
{
queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
}
}
private void DebugGridInstantMessage(GridInstantMessage im)

View File

@ -38,7 +38,7 @@ using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using PermissionMask = OpenSim.Framework.PermissionMask;
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
namespace OpenSim.Groups
{
@ -127,7 +127,7 @@ namespace OpenSim.Groups
m_debugEnabled = verbose;
MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled);
MainConsole.Instance.Output("{0} verbose logging set to {1}", null, Name, m_debugEnabled);
}
public void RegionLoaded(Scene scene)
@ -233,7 +233,7 @@ namespace OpenSim.Groups
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
//client.OnRequestAvatarProperties += OnRequestAvatarProperties;
client.OnRequestAvatarProperties += OnRequestAvatarProperties;
}
@ -261,7 +261,7 @@ namespace OpenSim.Groups
// Used for Notices and Group Invites/Accept/Reject
sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
}
/*
private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
{
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@ -269,7 +269,7 @@ namespace OpenSim.Groups
GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
}
*/
private void OnClientClosed(UUID AgentId, Scene scene)
{
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@ -281,7 +281,7 @@ namespace OpenSim.Groups
if (client != null)
{
client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
//client.OnRequestAvatarProperties -= OnRequestAvatarProperties;
client.OnRequestAvatarProperties -= OnRequestAvatarProperties;
// make child possible not called?
client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
client.OnInstantMessage -= OnInstantMessage;
@ -344,24 +344,14 @@ namespace OpenSim.Groups
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups]: OnInstantMessage called");
if(remoteClient == null || !remoteClient.IsActive || remoteClient.AgentId == UUID.Zero)
return;
Scene scene = (Scene)remoteClient.Scene;
if (scene == null)
return;
string remoteAgentIDstr = remoteClient.AgentId.ToString();
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
//m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog);
// Group invitations
if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
{
UUID inviteID = new UUID(im.imSessionID);
GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(remoteAgentIDstr, inviteID);
GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
if (inviteInfo == null)
{
@ -384,7 +374,7 @@ namespace OpenSim.Groups
// and the sessionid is the role
string reason = string.Empty;
if (!m_groupData.AddAgentToGroup(remoteAgentIDstr, invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason))
if (!m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason))
remoteClient.SendAgentAlertMessage("Unable to add you to the group: " + reason, false);
else
{
@ -411,106 +401,79 @@ namespace OpenSim.Groups
}
}
m_groupData.RemoveAgentToGroupInvite(remoteAgentIDstr, inviteID);
m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
}
// Reject
if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups]: Received a reject invite notice.");
if (m_debugEnabled) m_log.DebugFormat("[Groups]: Received a reject invite notice.");
m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
m_groupData.RemoveAgentToGroupInvite(remoteAgentIDstr, inviteID);
m_groupData.RemoveAgentFromGroup(remoteAgentIDstr, inviteInfo.AgentID, inviteInfo.GroupID);
m_groupData.RemoveAgentFromGroup(GetRequestingAgentIDStr(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID);
}
}
}
// Group notices
else if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
{
if (!m_groupNoticesEnabled)
{
return;
}
UUID GroupID = new UUID(im.toAgentID);
GroupMembershipData grpMemberData = m_groupData.GetAgentGroupMembership(remoteAgentIDstr, remoteAgentIDstr, GroupID);
if (grpMemberData == null)
if (m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), GroupID, null) != null)
{
remoteClient.SendAgentAlertMessage("Group membership not found", false);
return;
}
UUID NoticeID = UUID.Random();
string Subject = im.message.Substring(0, im.message.IndexOf('|'));
string Message = im.message.Substring(Subject.Length + 1);
if ((grpMemberData.GroupPowers & (ulong)GroupPowers.SendNotices) == 0)
{
remoteClient.SendAgentAlertMessage("No permission to send notice to group", false);
return;
}
InventoryItemBase item = null;
bool hasAttachment = false;
int index = im.message.IndexOf('|');
if (index < 0)
return;
string Subject = im.message.Substring(0, index);
string Message = im.message.Substring(index + 1);
UUID NoticeID = UUID.Random();
InventoryItemBase item = null;
bool hasAttachment = false;
if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
{
UUID itemID = UUID.Zero;
UUID ownerID = UUID.Zero;
try
if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
{
string binBucket = Utils.BytesToString(im.binaryBucket);
binBucket = binBucket.Substring(15); // remove extra LLSD pre header
OSDMap binBucketMAP = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
itemID = binBucketMAP["item_id"].AsUUID();
ownerID = binBucketMAP["owner_id"].AsUUID();
}
catch
{
m_log.DebugFormat("[GROUPS]: failed to decode group notice bucket");
return;
}
if (itemID != UUID.Zero && ownerID != UUID.Zero)
{
item = scene.InventoryService.GetItem(ownerID, itemID);
if(item != null)
{
if ((item.CurrentPermissions & (uint)(PermissionMask.Transfer | PermissionMask.Copy)) !=
(uint)(PermissionMask.Transfer | PermissionMask.Copy))
{
remoteClient.SendAgentAlertMessage("Item must be have Copy and Transfer rights to attach to group notice", false);
return;
}
}
hasAttachment = true;
}
}
string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
binBucket = binBucket.Remove(0, 14).Trim();
if (m_groupData.AddGroupNotice(remoteAgentIDstr, GroupID, NoticeID, im.fromAgentName, Subject, Message,
hasAttachment,
(byte)(item == null ? 0 : item.AssetType),
item == null ? null : item.Name,
item == null ? UUID.Zero : item.ID,
item == null ? UUID.Zero.ToString() : item.Owner.ToString()))
{
OnNewGroupNotice?.Invoke(GroupID, NoticeID);
// Send notice out to everyone that wants notices
foreach (GroupMembersData member in m_groupData.GetGroupMembers(remoteAgentIDstr, GroupID))
{
GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)InstantMessageDialog.GroupNotice);
if (member.AcceptNotices)
OSD binBucketOSD = OSDParser.DeserializeLLSDXml(binBucket);
if (binBucketOSD is OSDMap)
{
// Build notice IIM, one of reach, because the sending may be async
msg.toAgentID = member.AgentID.Guid;
OutgoingInstantMessage(msg, member.AgentID);
OSDMap binBucketMap = (OSDMap)binBucketOSD;
UUID itemID = binBucketMap["item_id"].AsUUID();
UUID ownerID = binBucketMap["owner_id"].AsUUID();
item = m_sceneList[0].InventoryService.GetItem(ownerID, itemID);
}
else
m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
}
if (m_groupData.AddGroupNotice(GetRequestingAgentIDStr(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message,
hasAttachment,
(byte)(item == null ? 0 : item.AssetType),
item == null ? null : item.Name,
item == null ? UUID.Zero : item.ID,
item == null ? UUID.Zero.ToString() : item.Owner.ToString()))
{
if (OnNewGroupNotice != null)
{
OnNewGroupNotice(GroupID, NoticeID);
}
// Send notice out to everyone that wants notices
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
{
if (member.AcceptNotices)
{
// Build notice IIM, one of reach, because the sending may be async
GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
msg.toAgentID = member.AgentID.Guid;
OutgoingInstantMessage(msg, member.AgentID);
}
}
}
}
@ -518,130 +481,41 @@ namespace OpenSim.Groups
if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
{
if (!m_groupNoticesEnabled)
if (im.binaryBucket.Length < 16) // Invalid
return;
//// 16 bytes are the UUID. Maybe.
// UUID folderID = new UUID(im.binaryBucket, 0);
UUID noticeID = new UUID(im.imSessionID);
if (m_debugEnabled)
m_log.DebugFormat("[xmlGROUPS]: Accepted notice {0} for {1}", noticeID, remoteClient.AgentId);
if (noticeID == UUID.Zero)
return;
UUID folderID = UUID.Zero;
try
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID);
if (notice != null)
{
if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
folderID = new UUID(im.binaryBucket, 0);
UUID giver = new UUID(im.toAgentID);
string tmp = string.Empty;
Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp);
m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
string message;
InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
giver, notice.noticeData.AttachmentItemID, out message);
if (itemCopy == null)
{
remoteClient.SendAgentAlertMessage(message, false);
return;
}
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
}
catch
{
m_log.DebugFormat("[xmlGROUPS]: GroupNoticeInventoryAccepted failed to decode target folder");
return;
}
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentIDstr, noticeID);
if (notice == null)
{
if (m_debugEnabled)
m_log.DebugFormat(
"[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
noticeID, remoteClient.AgentId);
return;
}
string tmp;
UUID giver = new UUID(im.toAgentID);
Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp);
m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
string message = "Could not find group notice attached item";
InventoryItemBase itemCopy = scene.GiveInventoryItem(remoteClient.AgentId,
giver, notice.noticeData.AttachmentItemID, folderID, out message);
if (itemCopy == null)
{
remoteClient.SendAgentAlertMessage(message, false);
return;
}
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
}
else if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryDeclined)
{
if (!m_groupNoticesEnabled)
return;
UUID noticeID = new UUID(im.imSessionID);
if (m_debugEnabled)
m_log.DebugFormat("[GROUPS]: Accepted notice {0} for {1}", noticeID, remoteAgentIDstr);
if (noticeID == UUID.Zero)
return;
UUID remoteAgentID = remoteClient.AgentId;
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentIDstr, noticeID);
if (notice == null)
{
if (m_debugEnabled)
m_log.DebugFormat(
"[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
noticeID, remoteClient.AgentId);
return;
}
string giver = notice.noticeData.AttachmentOwnerID;
UUID attachmentUUID = notice.noticeData.AttachmentItemID;
if (attachmentUUID == null ||
attachmentUUID == UUID.Zero ||
giver == null ||
giver == UUID.Zero.ToString()
)
return;
if (m_debugEnabled)
m_log.DebugFormat("[xmlGroups]: Deny inventory from {0} to {1}", giver, remoteAgentIDstr);
string message = String.Empty;
InventoryItemBase itemCopy = scene.InventoryService.GetItem(remoteAgentID, attachmentUUID);
if (itemCopy == null)
return;
InventoryFolderBase trash = scene.InventoryService.GetFolderForType(remoteAgentID, FolderType.Trash);
if (trash == null)
{
m_log.DebugFormat("[GROUPS]: failed to find trash folder for {0} ", remoteAgentID);
return;
}
if (itemCopy.Folder == trash.ID || remoteAgentIDstr == notice.noticeData.AttachmentOwnerID)
return;
itemCopy.Folder = trash.ID;
scene.InventoryService.MoveItems(itemCopy.Owner, new List<InventoryItemBase>() { itemCopy });
if (itemCopy == null)
{
remoteClient.SendAgentAlertMessage(message, false);
return;
}
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
}
// Interop, received special 210 code for ejecting a group member
// this only works within the comms servers domain, and won't work hypergrid
// TODO:FIXME: Use a presense server of some kind to find out where the
// client actually is, and try contacting that region directly to notify them,
// or provide the notification via xmlrpc update queue
else if ((im.dialog == 210))
if ((im.dialog == 210))
{
// This is sent from the region that the ejectee was ejected from
// if it's being delivered here, then the ejectee is here
@ -1075,7 +949,6 @@ namespace OpenSim.Groups
bucket = new byte[19 + name.Length];
bucket[0] = 1; // has attachment?
bucket[1] = info.noticeData.AttachmentType; // attachment type
info.GroupID.ToBytes(bucket, 2);
name.CopyTo(bucket, 18);
}
else
@ -1086,6 +959,7 @@ namespace OpenSim.Groups
bucket[18] = 0; // null terminated
}
info.GroupID.ToBytes(bucket, 2);
msg.binaryBucket = bucket;
}
else
@ -1334,7 +1208,7 @@ namespace OpenSim.Groups
public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
{
return m_groupData.FindGroups(remoteClient.AgentId.ToString(), query);
return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query);
}
#endregion

View File

@ -246,9 +246,9 @@ namespace OpenSim.Groups
return null;
}
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
{
return m_LocalGroupsConnector.FindGroups(RequestingAgentIDstr, search);
return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search);
}
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)

View File

@ -39,7 +39,7 @@ namespace OpenSim.Groups
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search);
List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search);
List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID);
bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason);

View File

@ -173,9 +173,9 @@ namespace OpenSim.Groups
return null;
}
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
{
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
return m_GroupsService.FindGroups(RequestingAgentID, search);
}
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)

View File

@ -153,7 +153,7 @@ namespace OpenSim.Groups
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
}
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string query)
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
{
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
if (string.IsNullOrEmpty(query))
@ -161,7 +161,7 @@ namespace OpenSim.Groups
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["Query"] = query;
sendData["RequestingAgentID"] = RequestingAgentIDstr;
sendData["RequestingAgentID"] = RequestingAgentID;
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);

View File

@ -192,10 +192,10 @@ namespace OpenSim.Groups
});
}
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
{
// TODO!
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
return m_GroupsService.FindGroups(RequestingAgentID, search);
}
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)

View File

@ -68,7 +68,6 @@ namespace OpenSim.Groups
GroupPowers.LandDeed |
GroupPowers.LandDivideJoin |
GroupPowers.LandEdit |
GroupPowers.AllowEnvironment |
GroupPowers.LandEjectAndFreeze |
GroupPowers.LandGardening |
GroupPowers.LandManageAllowed |

View File

@ -110,8 +110,9 @@ namespace OpenSim.OfflineIM
{
m_serializer.Serialize(writer, im);
writer.Flush();
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
}
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
}
OfflineIMData data = new OfflineIMData();

View File

@ -28,7 +28,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Reflection;
using System.Threading;
@ -50,9 +49,9 @@ namespace OpenSim.Framework.Capabilities
/// </summary>
public delegate IClientAPI GetClientDelegate(UUID agentID);
public class Caps : IDisposable
public class Caps
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_httpListenerHostName;
private uint m_httpListenPort;
@ -65,8 +64,8 @@ namespace OpenSim.Framework.Capabilities
private CapsHandlers m_capsHandlers;
private ConcurrentDictionary<string, PollServiceEventArgs> m_pollServiceHandlers
= new ConcurrentDictionary<string, PollServiceEventArgs>();
private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
= new Dictionary<string, PollServiceEventArgs>();
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
@ -126,9 +125,7 @@ namespace OpenSim.Framework.Capabilities
None = 0,
SentSeeds = 1,
ObjectAnim = 0x100,
WLEnv = 0x200,
AdvEnv = 0x400
ObjectAnim = 0x10
}
public CapsFlags Flags { get; set;}
@ -165,23 +162,6 @@ namespace OpenSim.Framework.Capabilities
m_capsActive = null;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
Flags = CapsFlags.None;
if (m_capsActive != null)
{
DeregisterHandlers();
m_capsActive.Dispose();
m_capsActive = null;
}
}
/// <summary>
/// Register a handler. This allows modules to register handlers.
@ -194,27 +174,15 @@ namespace OpenSim.Framework.Capabilities
m_capsHandlers[capName] = handler;
}
public void RegisterSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
{
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
m_capsHandlers.AddSimpleHandler(capName, handler, addToListener);
}
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
{
// m_log.DebugFormat(
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
if(!m_pollServiceHandlers.TryAdd(capName, pollServiceHandler))
{
m_log.ErrorFormat(
"[CAPS]: Handler with name {0} already registered (ulr {1}, agent {2}, region {3}",
capName, pollServiceHandler.Url, m_agentID, m_regionName);
return;
}
m_pollServiceHandlers.Add(capName, pollServiceHandler);
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler);
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
// string protocol = "http";
@ -254,7 +222,7 @@ namespace OpenSim.Framework.Capabilities
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
{
m_httpListener.RemovePollServiceHTTPHandler(handler.Url);
m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
}
m_pollServiceHandlers.Clear();
}
@ -295,6 +263,9 @@ namespace OpenSim.Framework.Capabilities
port = MainServer.Instance.SSLPort;
protocol = "https";
}
//
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
}
}
@ -308,7 +279,7 @@ namespace OpenSim.Framework.Capabilities
caps[kvp.Key] = kvp.Value;
}
Flags |= CapsFlags.SentSeeds;
return caps;
}

View File

@ -27,7 +27,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
@ -41,7 +40,6 @@ namespace OpenSim.Framework.Capabilities
public class CapsHandlers
{
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
private ConcurrentDictionary<string, ISimpleStreamHandler> m_capsSimpleHandlers = new ConcurrentDictionary<string, ISimpleStreamHandler>();
private IHttpServer m_httpListener;
private string m_httpListenerHostName;
private uint m_httpListenerPort;
@ -75,35 +73,17 @@ namespace OpenSim.Framework.Capabilities
{
lock (m_capsHandlers)
{
if(m_capsHandlers.ContainsKey(capsName))
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
}
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
m_capsHandlers.Remove(capsName);
}
if(m_capsSimpleHandlers.TryRemove(capsName, out ISimpleStreamHandler hdr))
{
m_httpListener.RemoveSimpleStreamHandler(hdr.Path);
}
}
public void AddSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
{
if(ContainsCap(capName))
Remove(capName);
if(m_capsSimpleHandlers.TryAdd(capName, handler) && addToListener)
m_httpListener.AddSimpleStreamHandler(handler);
}
public bool ContainsCap(string cap)
{
lock (m_capsHandlers)
if (m_capsHandlers.ContainsKey(cap))
return true;
return m_capsSimpleHandlers.ContainsKey(cap);
return m_capsHandlers.ContainsKey(cap);
}
/// <summary>
@ -130,9 +110,6 @@ namespace OpenSim.Framework.Capabilities
if (m_capsHandlers.ContainsKey(idx))
{
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[idx].Path);
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[idx].Path);
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[idx].Path);
m_capsHandlers.Remove(idx);
}
@ -154,9 +131,8 @@ namespace OpenSim.Framework.Capabilities
{
lock (m_capsHandlers)
{
string[] __keys = new string[m_capsHandlers.Keys.Count + m_capsSimpleHandlers.Keys.Count];
string[] __keys = new string[m_capsHandlers.Keys.Count];
m_capsHandlers.Keys.CopyTo(__keys, 0);
m_capsSimpleHandlers.Keys.CopyTo(__keys, m_capsHandlers.Keys.Count);
return __keys;
}
}
@ -170,39 +146,24 @@ namespace OpenSim.Framework.Capabilities
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
{
Hashtable caps = new Hashtable();
string protocol = "http://";
if (m_useSSL)
protocol = "https://";
string protocol = m_useSSL ? "https://" : "http://";
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
if (requestedCaps == null)
{
lock (m_capsHandlers)
{
foreach (KeyValuePair<string, ISimpleStreamHandler> kvp in m_capsSimpleHandlers)
caps[kvp.Key] = baseUrl + kvp.Value.Path;
foreach (KeyValuePair<string, IRequestHandler> kvp in m_capsHandlers)
caps[kvp.Key] = baseUrl + kvp.Value.Path;
}
return caps;
}
lock (m_capsHandlers)
{
for(int i = 0; i < requestedCaps.Count; ++i)
foreach (string capsName in m_capsHandlers.Keys)
{
string capsName = requestedCaps[i];
if (excludeSeed && "SEED" == capsName)
continue;
if (m_capsSimpleHandlers.TryGetValue(capsName, out ISimpleStreamHandler shdr))
{
caps[capsName] = baseUrl + shdr.Path;
if (requestedCaps != null && !requestedCaps.Contains(capsName))
continue;
}
if (m_capsHandlers.TryGetValue(capsName, out IRequestHandler chdr))
{
caps[capsName] = baseUrl + chdr.Path;
}
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
}
}

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Web;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
//using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers
{
public class AvatarPickerSearchHandler : BaseStreamHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IPeople m_PeopleService;
public AvatarPickerSearchHandler(string path, IPeople peopleService, string name, string description)
: base("GET", path, name, description)
{
m_PeopleService = peopleService;
}
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
// Try to parse the texture ID from the request URL
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string names = query.GetOne("names");
string psize = query.GetOne("page_size");
string pnumber = query.GetOne("page");
if (m_PeopleService == null)
return FailureResponse(names, (int)System.Net.HttpStatusCode.InternalServerError, httpResponse);
if (string.IsNullOrEmpty(names) || names.Length < 3)
return FailureResponse(names, (int)System.Net.HttpStatusCode.BadRequest, httpResponse);
m_log.DebugFormat("[AVATAR PICKER SEARCH]: search for {0}", names);
int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize));
int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber));
// Full content request
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
//httpResponse.ContentLength = ??;
httpResponse.ContentType = "application/llsd+xml";
List<UserData> users = m_PeopleService.GetUserData(names, page_size, page_number);
LLSDAvatarPicker osdReply = new LLSDAvatarPicker();
osdReply.next_page_url = httpRequest.RawUrl;
foreach (UserData u in users)
osdReply.agents.Array.Add(ConvertUserData(u));
string reply = LLSDHelpers.SerialiseLLSDReply(osdReply);
return System.Text.Encoding.UTF8.GetBytes(reply);
}
private LLSDPerson ConvertUserData(UserData user)
{
LLSDPerson p = new LLSDPerson();
p.legacy_first_name = user.FirstName;
p.legacy_last_name = user.LastName;
p.display_name = user.FirstName + " " + user.LastName;
if (user.LastName.StartsWith("@"))
p.username = user.FirstName.ToLower() + user.LastName.ToLower();
else
p.username = user.FirstName.ToLower() + "." + user.LastName.ToLower();
p.id = user.Id;
p.is_display_name_default = false;
return p;
}
private byte[] FailureResponse(string names, int statuscode, IOSHttpResponse httpResponse)
{
m_log.Error("[AVATAR PICKER SEARCH]: Error searching for " + names);
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return System.Text.Encoding.UTF8.GetBytes(string.Empty);
}
}
}

View File

@ -28,7 +28,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
@ -38,10 +37,10 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers
{
@ -50,10 +49,10 @@ namespace OpenSim.Capabilities.Handlers
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
private IInventoryService m_InventoryService;
private ILibraryService m_LibraryService;
private IScene m_Scene;
// private object m_fetchLock = new Object();
public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
{
@ -62,86 +61,52 @@ namespace OpenSim.Capabilities.Handlers
m_Scene = s;
}
public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey<UUID> BadRequests)
public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
//m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
List<LLSDFetchInventoryDescendents> folders = null;
List<UUID> bad_folders = new List<UUID>();
Hashtable hash = new Hashtable();
try
{
OSDArray foldersrequested = null;
OSD tmp = OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
OSDMap map = (OSDMap)tmp;
if(map.TryGetValue("folders", out tmp) && tmp is OSDArray)
foldersrequested = tmp as OSDArray;
if (foldersrequested == null || foldersrequested.Count == 0)
{
httpResponse.RawBuffer = EmptyResponse;
return;
}
folders = new List<LLSDFetchInventoryDescendents>(foldersrequested.Count);
for (int i = 0; i < foldersrequested.Count; i++)
{
OSDMap mfolder = foldersrequested[i] as OSDMap;
UUID id = mfolder["folder_id"].AsUUID();
if(BadRequests.ContainsKey(id))
{
bad_folders.Add(id);
}
else
{
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
try
{
llsdRequest.folder_id = id;
llsdRequest.owner_id = mfolder["owner_id"].AsUUID();
llsdRequest.sort_order = mfolder["sort_order"].AsInteger();
llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean();
llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean();
}
catch (Exception e)
{
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message);
continue;
}
folders.Add(llsdRequest);
}
}
foldersrequested = null;
tmp = null;
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
}
catch (Exception e)
catch (LLSD.LLSDParseException e)
{
m_log.ErrorFormat("[FETCH INV DESC]: fail parsing request: {0}", e.Message);
httpResponse.RawBuffer = EmptyResponse;
return;
m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
m_log.Error("Request: " + request);
}
if (folders == null || folders.Count == 0)
ArrayList foldersrequested = (ArrayList)hash["folders"];
hash.Clear();
List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>();
for (int i = 0; i < foldersrequested.Count; i++)
{
if(bad_folders.Count == 0)
Hashtable inventoryhash = (Hashtable)foldersrequested[i];
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
try
{
httpResponse.RawBuffer = EmptyResponse;
return;
LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
}
StringBuilder sb = osStringBuilderCache.Acquire();
sb.Append("<llsd><map><key>folders</key><array /></map><map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders)
catch (Exception e)
{
sb.Append("<map><key>folder_id</key><uuid>");
sb.Append(bad.ToString());
sb.Append("</uuid><key>error</key><string>Unknown</string></map>");
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
continue;
}
sb.Append("</array></map></llsd>");
httpResponse.RawBuffer = Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb));
folders.Add(llsdRequest);
}
foldersrequested.Clear();
if(folders.Count == 0)
return "<llsd><map><key>folders</key><array /></map></llsd>";
List<UUID> bad_folders = new List<UUID>();
int total_folders = 0;
int total_items = 0;
List<InventoryCollection> invcollSet = Fetch(folders, bad_folders, ref total_folders, ref total_items);
//m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
@ -157,57 +122,57 @@ namespace OpenSim.Capabilities.Handlers
StringBuilder lastresponse = new StringBuilder(mem);
lastresponse.Append("<llsd>");
if (invcollSetCount > 0)
if(invcollSetCount > 0)
{
lastresponse.Append("<map><key>folders</key><array>");
int i = 0;
InventoryCollection thiscoll;
for (i = 0; i < invcollSetCount; i++)
for(i = 0; i < invcollSetCount; i++)
{
thiscoll = invcollSet[i];
invcollSet[i] = null;
LLSDxmlEncode.AddMap(lastresponse);
LLSDxmlEncode.AddElem("agent_id", thiscoll.OwnerID, lastresponse);
LLSDxmlEncode.AddElem("descendents", thiscoll.Descendents, lastresponse);
LLSDxmlEncode.AddElem("folder_id", thiscoll.FolderID, lastresponse);
LLSDxmlEncode.AddElem("agent_id", thiscoll.OwnerID, lastresponse);
LLSDxmlEncode.AddElem("descendents", thiscoll.Descendents, lastresponse);
LLSDxmlEncode.AddElem("folder_id", thiscoll.FolderID, lastresponse);
if (thiscoll.Folders == null || thiscoll.Folders.Count == 0)
LLSDxmlEncode.AddEmptyArray("categories", lastresponse);
else
{
LLSDxmlEncode.AddArray("categories", lastresponse);
foreach (InventoryFolderBase invFolder in thiscoll.Folders)
if(thiscoll.Folders == null || thiscoll.Folders.Count == 0)
LLSDxmlEncode.AddEmptyArray("categories", lastresponse);
else
{
LLSDxmlEncode.AddMap(lastresponse);
LLSDxmlEncode.AddArray("categories", lastresponse);
foreach (InventoryFolderBase invFolder in thiscoll.Folders)
{
LLSDxmlEncode.AddMap(lastresponse);
LLSDxmlEncode.AddElem("folder_id", invFolder.ID, lastresponse);
LLSDxmlEncode.AddElem("parent_id", invFolder.ParentID, lastresponse);
LLSDxmlEncode.AddElem("name", invFolder.Name, lastresponse);
LLSDxmlEncode.AddElem("type", invFolder.Type, lastresponse);
LLSDxmlEncode.AddElem("preferred_type", (int)-1, lastresponse);
LLSDxmlEncode.AddElem("version", invFolder.Version, lastresponse);
LLSDxmlEncode.AddElem("folder_id", invFolder.ID, lastresponse);
LLSDxmlEncode.AddElem("parent_id", invFolder.ParentID, lastresponse);
LLSDxmlEncode.AddElem("name", invFolder.Name, lastresponse);
LLSDxmlEncode.AddElem("type", invFolder.Type, lastresponse);
LLSDxmlEncode.AddElem("preferred_type", (int)-1, lastresponse);
LLSDxmlEncode.AddElem("version", invFolder.Version, lastresponse);
LLSDxmlEncode.AddEndMap(lastresponse);
}
LLSDxmlEncode.AddEndArray(lastresponse);
}
if (thiscoll.Items == null || thiscoll.Items.Count == 0)
LLSDxmlEncode.AddEmptyArray("items", lastresponse);
else
{
LLSDxmlEncode.AddArray("items", lastresponse);
foreach (InventoryItemBase invItem in thiscoll.Items)
{
invItem.ToLLSDxml(lastresponse);
LLSDxmlEncode.AddEndMap(lastresponse);
}
LLSDxmlEncode.AddEndArray(lastresponse);
}
LLSDxmlEncode.AddEndArray(lastresponse);
}
if(thiscoll.Items == null || thiscoll.Items.Count == 0)
LLSDxmlEncode.AddEmptyArray("items", lastresponse);
else
{
LLSDxmlEncode.AddArray("items", lastresponse);
foreach (InventoryItemBase invItem in thiscoll.Items)
{
invItem.ToLLSDxml(lastresponse);
}
LLSDxmlEncode.AddElem("owner_id", thiscoll.OwnerID, lastresponse);
LLSDxmlEncode.AddElem("version", thiscoll.Version, lastresponse);
LLSDxmlEncode.AddEndArray(lastresponse);
}
LLSDxmlEncode.AddElem("owner_id", thiscoll.OwnerID, lastresponse);
LLSDxmlEncode.AddElem("version", thiscoll.Version, lastresponse);
LLSDxmlEncode.AddEndMap(lastresponse);
invcollSet[i] = null;
@ -221,12 +186,11 @@ namespace OpenSim.Capabilities.Handlers
}
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
if (bad_folders.Count > 0)
if(bad_folders.Count > 0)
{
lastresponse.Append("<map><key>bad_folders</key><array>");
foreach (UUID bad in bad_folders)
{
BadRequests.Add(bad);
lastresponse.Append("<map><key>folder_id</key><uuid>");
lastresponse.Append(bad.ToString());
lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>");
@ -235,7 +199,7 @@ namespace OpenSim.Capabilities.Handlers
}
lastresponse.Append("</llsd>");
httpResponse.RawBuffer = Util.UTF8NBGetbytes(lastresponse.ToString());
return lastresponse.ToString();
}
private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollection> result, ref int total_folders, ref int total_items)
@ -425,7 +389,7 @@ namespace OpenSim.Capabilities.Handlers
if (linked != null)
{
List<InventoryItemBase> linkedItems = new List<InventoryItemBase>(linked.Length);
List<InventoryItemBase> linkedItems = new List<InventoryItemBase>();
// check for broken
foreach (InventoryItemBase linkedItem in linked)
{

View File

@ -29,12 +29,9 @@ using System;
using Nini.Config;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Capabilities.Handlers
{
@ -70,16 +67,16 @@ namespace OpenSim.Capabilities.Handlers
m_LibraryService =
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
ISimpleStreamHandler reqHandler
= new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests);
});
server.AddSimpleStreamHandler(reqHandler);
IRequestHandler reqHandler
= new RestStreamHandler(
"POST",
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
webFetchHandler.FetchInventoryDescendentsRequest,
"FetchInvDescendents",
null);
server.AddStreamHandler(reqHandler);
}
}
}

View File

@ -25,12 +25,12 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Net;
using System.Reflection;
using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
@ -105,62 +105,7 @@ namespace OpenSim.Capabilities.Handlers
}
LLSDxmlEncode.AddEndMap(lsl);
return LLSDxmlEncode.End(lsl);
}
public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
{
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
if(BadRequests == null)
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
OSDArray itemsRequested = (OSDArray)requestmap["items"];
UUID[] itemIDs = new UUID[itemsRequested.Count];
int i = 0;
foreach (OSDMap osdItemId in itemsRequested)
{
UUID id = osdItemId["item_id"].AsUUID();
if(!BadRequests.ContainsKey(id))
itemIDs[i++] = id;
}
InventoryItemBase[] items = null;
try
{
// badrequests still not filled
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
}
catch{ }
StringBuilder lsl = LLSDxmlEncode.Start(4096);
LLSDxmlEncode.AddMap(lsl);
LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
if (items == null || items.Length == 0)
{
LLSDxmlEncode.AddEmptyArray("items", lsl);
}
else
{
LLSDxmlEncode.AddArray("items", lsl);
foreach (InventoryItemBase item in items)
{
if (item != null)
item.ToLLSDxml(lsl, 0xff);
}
LLSDxmlEncode.AddEndArray(lsl);
}
LLSDxmlEncode.AddEndMap(lsl);
httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(lsl));
httpResponse.StatusCode = (int)HttpStatusCode.OK;
return LLSDxmlEncode.End(lsl);;
}
}
}

View File

@ -28,7 +28,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using log4net;
using log4net.Config;
@ -127,19 +127,6 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
Console.WriteLine("Number of descendents: " + m_rootDescendents);
}
private string dorequest(FetchInvDescHandler handler, string request)
{
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
using(ExpiringKey<UUID> bad = new ExpiringKey<UUID>(5000)) // bad but this is test
using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false))
{
req.InputStream = ms;
handler.FetchInventoryDescendentsRequest(req, resp, bad);
}
return Util.UTF8.GetString(resp.RawBuffer);
}
[Test]
public void Test_001_SimpleFolder()
{
@ -148,6 +135,8 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
Init();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
request += m_rootFolderID;
@ -155,7 +144,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
request += m_userID.ToString();
request += "</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
string llsdresponse = dorequest(handler, request);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
@ -172,6 +161,8 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
TestHelpers.InMethod();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
string request = "<llsd><map><key>folders</key><array>";
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
@ -182,7 +173,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
request += "</array></map></llsd>";
string llsdresponse = dorequest(handler, request);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Console.WriteLine(llsdresponse);
string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
@ -200,12 +191,14 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
TestHelpers.InMethod();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
request += "f0000000-0000-0000-0000-00000000000f";
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
string llsdresponse = dorequest(handler, request);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Console.WriteLine(llsdresponse);
string descendents = "descendents</key><integer>2</integer>";
@ -242,6 +235,8 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
TestHelpers.InMethod();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
string request = "<llsd><map><key>folders</key><array>";
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
@ -258,7 +253,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
request += "</array></map></llsd>";
string llsdresponse = dorequest(handler, request);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Console.WriteLine(llsdresponse);
string root_folder = "<key>folder_id</key><uuid>" + m_rootFolderID + "</uuid>";
@ -281,12 +276,14 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
Init();
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
TestOSHttpRequest req = new TestOSHttpRequest();
TestOSHttpResponse resp = new TestOSHttpResponse();
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
request += UUID.Zero;
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
string llsdresponse = dorequest(handler, request);
string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");

View File

@ -28,8 +28,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using OpenMetaverse;
@ -66,8 +68,7 @@ namespace OpenSim.Capabilities.Handlers
{"jpeg_id", AssetType.ImageJPEG},
{"animatn_id", AssetType.Animation},
{"gesture_id", AssetType.Gesture},
{"mesh_id", AssetType.Mesh},
{"settings_id", AssetType.Settings}
{"mesh_id", AssetType.Mesh}
};
private IAssetService m_assetService;
@ -77,68 +78,82 @@ namespace OpenSim.Capabilities.Handlers
m_assetService = assService;
}
public void Handle(OSHttpRequest req, OSHttpResponse response)
public Hashtable Handle(Hashtable request)
{
response.ContentType = "text/plain";
Hashtable responsedata = new Hashtable();
responsedata["content_type"] = "text/plain";
responsedata["int_bytes"] = 0;
if (m_assetService == null)
{
response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
response.KeepAlive = false;
return;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.ServiceUnavailable;
responsedata["str_response_string"] = "The asset service is unavailable";
responsedata["keepalive"] = false;
return responsedata;
}
response.StatusCode = (int)HttpStatusCode.BadRequest;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
var queries = req.QueryAsDictionary;
if(queries.Count == 0)
return;
string[] queries = null;
if(request.Contains("querystringkeys"))
queries = (string[])request["querystringkeys"];
if(queries == null || queries.Length == 0)
return responsedata;
string query = queries[0];
if(!queryTypes.ContainsKey(query))
{
m_log.Warn("[GETASSET]: Unknown type: " + query);
return responsedata;
}
AssetType type = queryTypes[query];
AssetType type = AssetType.Unknown;
string assetStr = string.Empty;
foreach (KeyValuePair<string,string> kvp in queries)
{
if (queryTypes.ContainsKey(kvp.Key))
{
type = queryTypes[kvp.Key];
assetStr = kvp.Value;
break;
}
}
if(type == AssetType.Unknown)
{
//m_log.Warn("[GETASSET]: Unknown type: " + query);
m_log.Warn("[GETASSET]: Unknown type");
response.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
if (request.ContainsKey(query))
assetStr = request[query].ToString();
if (String.IsNullOrEmpty(assetStr))
return;
return responsedata;
UUID assetID = UUID.Zero;
if(!UUID.TryParse(assetStr, out assetID))
return;
return responsedata;
AssetBase asset = m_assetService.Get(assetID.ToString());
if(asset == null)
{
// m_log.Warn("[GETASSET]: not found: " + query + " " + assetStr);
response.StatusCode = (int)HttpStatusCode.NotFound;
return;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
responsedata["str_response_string"] = "Asset not found.";
return responsedata;
}
if (asset.Type != (sbyte)type)
return;
{
responsedata["str_response_string"] = "Got wrong asset type";
return responsedata;
}
int len = asset.Data.Length;
if(type == AssetType.Mesh || type == AssetType.Texture)
responsedata["throttle"] = true;
string range = null;
if (req.Headers["Range"] != null)
range = req.Headers["Range"];
else if (req.Headers["range"] != null)
range = req.Headers["range"];
responsedata["content_type"] = asset.Metadata.ContentType;
responsedata["bin_response_data"] = asset.Data;
responsedata["int_bytes"] = asset.Data.Length;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
string range = String.Empty;
if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"];
else
return responsedata; // full asset
if (String.IsNullOrEmpty(range))
return responsedata; // full asset
// range request
int start, end;
@ -148,8 +163,8 @@ namespace OpenSim.Capabilities.Handlers
// sending back the last byte instead of an error status
if (start >= asset.Data.Length)
{
response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
return;
responsedata["str_response_string"] = "This range doesnt exist.";
return responsedata;
}
if (end == -1)
@ -158,33 +173,20 @@ namespace OpenSim.Capabilities.Handlers
end = Utils.Clamp(end, 0, asset.Data.Length - 1);
start = Utils.Clamp(start, 0, end);
len = end - start + 1;
int len = end - start + 1;
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length));
response.StatusCode = (int)HttpStatusCode.PartialContent;
response.RawBufferStart = start;
Hashtable headers = new Hashtable();
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length);
responsedata["headers"] = headers;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
responsedata["bin_start"] = start;
responsedata["int_bytes"] = len;
return responsedata;
}
else
response.StatusCode = (int)HttpStatusCode.OK;
response.ContentType = asset.Metadata.ContentType;
response.RawBuffer = asset.Data;
response.RawBufferLen = len;
if (type == AssetType.Mesh || type == AssetType.Texture)
{
if(len > 8196)
{
//if(type == AssetType.Texture && ((asset.Flags & AssetFlags.AvatarBake)!= 0))
// responsedata["prio"] = 1;
//else
response.Priority = 2;
}
else
response.Priority = 1;
}
else
response.Priority = -1;
m_log.Warn("[GETASSETS]: Failed to parse a range, sending full asset: " + assetStr);
return responsedata;
}
}
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
namespace OpenSim.Capabilities.Handlers
{
public class GetDisplayNamesHandler : BaseStreamHandler
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected IUserManagement m_UserManagement;
public GetDisplayNamesHandler(string path, IUserManagement umService, string name, string description)
: base("GET", path, name, description)
{
m_UserManagement = umService;
}
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
// m_log.DebugFormat("[GET_DISPLAY_NAMES]: called {0}", httpRequest.Url.Query);
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string[] ids = query.GetValues("ids");
if (m_UserManagement == null)
{
m_log.Error("[GET_DISPLAY_NAMES]: Cannot fetch display names without a user management component");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
return new byte[0];
}
Dictionary<UUID,string> names = m_UserManagement.GetUsersNames(ids, UUID.Zero);
OSDMap osdReply = new OSDMap();
OSDArray agents = new OSDArray();
osdReply["agents"] = agents;
foreach (KeyValuePair<UUID,string> kvp in names)
{
if (string.IsNullOrEmpty(kvp.Value))
continue;
if(kvp.Key == UUID.Zero)
continue;
string[] parts = kvp.Value.Split(new char[] {' '});
OSDMap osdname = new OSDMap();
if(parts[0] == "Unknown")
{
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2));
}
else
{
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1));
}
osdname["display_name"] = OSD.FromString(kvp.Value);
osdname["legacy_first_name"] = parts[0];
osdname["legacy_last_name"] = parts[1];
osdname["username"] = OSD.FromString(kvp.Value);
osdname["id"] = OSD.FromUUID(kvp.Key);
osdname["is_display_name_default"] = OSD.FromBoolean(true);
agents.Add(osdname);
}
// Full content request
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
//httpResponse.ContentLength = ??;
httpResponse.ContentType = "application/llsd+xml";
string reply = OSDParser.SerializeLLSDXmlString(osdReply);
return System.Text.Encoding.UTF8.GetBytes(reply);
}
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Nini.Config;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using OpenMetaverse;
namespace OpenSim.Capabilities.Handlers
{
public class GetDisplayNamesServerConnector : ServiceConnector
{
private IUserManagement m_UserManagement;
private string m_ConfigName = "CapsService";
public GetDisplayNamesServerConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
if (configName != String.Empty)
m_ConfigName = configName;
IConfig serverConfig = config.Configs[m_ConfigName];
if (serverConfig == null)
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
string umService = serverConfig.GetString("AssetService", String.Empty);
if (umService == String.Empty)
throw new Exception("No AssetService in config file");
Object[] args = new Object[] { config };
m_UserManagement =
ServerUtils.LoadPlugin<IUserManagement>(umService, args);
if (m_UserManagement == null)
throw new Exception(String.Format("Failed to load UserManagement from {0}; config is {1}", umService, m_ConfigName));
server.AddStreamHandler(
new GetDisplayNamesHandler("/CAPS/agents/", m_UserManagement, "GetDisplayNames", null));
}
}
}

View File

@ -68,7 +68,7 @@ namespace OpenSim.Capabilities.Handlers
IRequestHandler reqHandler
= new RestHTTPHandler(
"GET",
"/" + UUID.Random(),
"/CAPS/" + UUID.Random(),
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
"GetMesh",
null);

View File

@ -32,7 +32,6 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.IO;
using System.Net;
using System.Web;
using log4net;
using Nini.Config;
@ -137,8 +136,8 @@ namespace OpenSim.Capabilities.Handlers
{
string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString();
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
httpResponse.StatusCode = (int)HttpStatusCode.Moved;
httpResponse.AddHeader("Location:", textureUrl);
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
httpResponse.RedirectLocation = textureUrl;
return true;
}
@ -239,9 +238,8 @@ namespace OpenSim.Capabilities.Handlers
response.ContentLength = len;
response.ContentType = texture.Metadata.ContentType;
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
response.RawBuffer = texture.Data;
response.RawBufferStart = start;
response.RawBufferLen = len;
response.Body.Write(texture.Data, start, len);
}
}
else
@ -259,19 +257,17 @@ namespace OpenSim.Capabilities.Handlers
response.ContentType = texture.Metadata.ContentType;
else
response.ContentType = "image/" + format;
response.RawBuffer = texture.Data;
response.RawBufferStart = 0;
response.RawBufferLen = texture.Data.Length;
response.Body.Write(texture.Data, 0, texture.Data.Length);
}
// if (response.StatusCode < 200 || response.StatusCode > 299)
// m_log.WarnFormat(
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
// else
// m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
// if (response.StatusCode < 200 || response.StatusCode > 299)
// m_log.WarnFormat(
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
// else
// m_log.DebugFormat(
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
}
/// <summary>

View File

@ -66,7 +66,7 @@ namespace OpenSim.Capabilities.Handlers
string rurl = serverConfig.GetString("GetTextureRedirectURL");
;
server.AddStreamHandler(
new GetTextureRobustHandler("/CAPS/GetTexture", m_AssetService, "GetTexture", null, rurl));
new GetTextureRobustHandler("/CAPS/GetTexture/", m_AssetService, "GetTexture", null, rurl));
}
}
}

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Capabilities.Handlers
{
public class UploadBakedTextureHandler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Caps m_HostCapsObj;
private IAssetService m_assetService;
public UploadBakedTextureHandler(Caps caps, IAssetService assetService)
{
m_HostCapsObj = caps;
m_assetService = assetService;
}
/// <summary>
/// Handle a request from the client for a Uri to upload a baked texture.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <param name="httpRequest"></param>
/// <param name="httpResponse"></param>
/// <returns>The upload response if the request is successful, null otherwise.</returns>
public string UploadBakedTexture(
string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
try
{
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
BakedTextureUploader uploader =
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID);
uploader.OnUpLoad += BakedTextureUploaded;
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler(
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
string protocol = "http://";
if (m_HostCapsObj.SSLCaps)
protocol = "https://";
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
catch (Exception e)
{
m_log.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace);
}
return null;
}
/// <summary>
/// Called when a baked texture has been successfully uploaded by a client.
/// </summary>
/// <param name="assetID"></param>
/// <param name="data"></param>
private void BakedTextureUploaded(UUID assetID, byte[] data)
{
m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
AssetBase asset;
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
asset.Data = data;
asset.Temporary = true;
asset.Local = true;
m_assetService.Store(asset);
}
}
class BakedTextureUploader
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public event Action<UUID, byte[]> OnUpLoad;
private string uploaderPath = String.Empty;
private UUID newAssetID;
private IHttpServer httpListener;
private UUID AgentId = UUID.Zero;
public BakedTextureUploader(string path, IHttpServer httpServer, UUID uUID)
{
newAssetID = UUID.Random();
uploaderPath = path;
httpListener = httpServer;
AgentId = uUID;
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
}
/// <summary>
/// Handle raw uploaded baked texture data.
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
// Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
// on another thread which might send out avatar updates before the asset has been put into the asset
// service.
if (handlerUpLoad != null)
handlerUpLoad(newAssetID, data);
string res = String.Empty;
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
uploadComplete.new_asset = newAssetID.ToString();
uploadComplete.new_inventory_item = UUID.Zero;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
return res;
}
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Nini.Config;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using OpenMetaverse;
namespace OpenSim.Capabilities.Handlers
{
public class UploadBakedTextureServerConnector : ServiceConnector
{
private IAssetService m_AssetService;
private string m_ConfigName = "CapsService";
public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
if (configName != String.Empty)
m_ConfigName = configName;
IConfig serverConfig = config.Configs[m_ConfigName];
if (serverConfig == null)
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
string assetService = serverConfig.GetString("AssetService", String.Empty);
if (assetService == String.Empty)
throw new Exception("No AssetService in config file");
Object[] args = new Object[] { config };
m_AssetService =
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
if (m_AssetService == null)
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
// NEED TO FIX THIS
OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
server.AddStreamHandler(new RestStreamHandler(
"POST",
"/CAPS/UploadBakedTexture/",
new UploadBakedTextureHandler(caps, m_AssetService).UploadBakedTexture,
"UploadBakedTexture",
"Upload Baked Texture Capability"));
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDItemUpdate
{
public UUID item_id;
public LLSDItemUpdate()
{
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System.Collections;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDParcelVoiceInfoResponse
{
public int parcel_local_id;
public string region_name;
public Hashtable voice_credentials;
public LLSDParcelVoiceInfoResponse()
{
}
public LLSDParcelVoiceInfoResponse(string region, int localID, Hashtable creds)
{
region_name = region;
parcel_local_id = localID;
voice_credentials = creds;
}
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenMetaverse;
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDTaskScriptUpdate
{
/// <summary>
/// The item containing the script to update
/// </summary>
public UUID item_id;
/// <summary>
/// The task containing the script
/// </summary>
public UUID task_id;
/// <summary>
/// Signals whether the script is currently active
/// </summary>
public int is_script_running;
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OpenSim.Framework.Capabilities
{
[OSDMap]
public class LLSDVoiceAccountResponse
{
public string username;
public string password;
public string voice_sip_uri_hostname;
public string voice_account_server_name;
public LLSDVoiceAccountResponse()
{
}
public LLSDVoiceAccountResponse(string user, string pass)
{
username = user;
password = pass;
}
public LLSDVoiceAccountResponse(string user, string pass, string sipUriHost, string accountServer)
{
username = user;
password = pass;
voice_sip_uri_hostname = sipUriHost;
voice_account_server_name = accountServer;
}
}
}

View File

@ -80,7 +80,7 @@ namespace OpenSim.ConsoleClient
while (m_Server.Running)
{
System.Threading.Thread.Sleep(500);
MainConsole.Instance.Prompt();
// MainConsole.Instance.Prompt();
}
if (pidFile != String.Empty)

View File

@ -29,13 +29,16 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Threading;
using log4net;
using MySql.Data.MySqlClient;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Data;
namespace OpenSim.Data.MySQL
{
@ -127,6 +130,10 @@ namespace OpenSim.Data.MySQL
// Eligibility check
//
// PrimFlags.Temporary is not used in OpenSim code and cannot
// be guaranteed to always be clear. Don't check it.
// if ((flags & (uint)PrimFlags.Temporary) != 0)
// return;
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
return;
@ -147,15 +154,16 @@ namespace OpenSim.Data.MySQL
"Name, Text, Description, " +
"SitName, TouchName, ObjectFlags, " +
"OwnerMask, NextOwnerMask, GroupMask, " +
"EveryoneMask, BaseMask, " +
"PositionX, PositionY, PositionZ, " +
"GroupPositionX, GroupPositionY, GroupPositionZ, " +
"VelocityX, VelocityY, VelocityZ, " +
"AngularVelocityX, AngularVelocityY, AngularVelocityZ, " +
"AccelerationX, AccelerationY, AccelerationZ, " +
"standtargetx, standtargety, standtargetz, " +
"RotationX, RotationY, RotationZ, RotationW, " +
"SitTargetOffsetX, SitTargetOffsetY, SitTargetOffsetZ, " +
"EveryoneMask, BaseMask, PositionX, " +
"PositionY, PositionZ, GroupPositionX, " +
"GroupPositionY, GroupPositionZ, VelocityX, " +
"VelocityY, VelocityZ, AngularVelocityX, " +
"AngularVelocityY, AngularVelocityZ, " +
"AccelerationX, AccelerationY, " +
"AccelerationZ, RotationX, " +
"RotationY, RotationZ, " +
"RotationW, SitTargetOffsetX, " +
"SitTargetOffsetY, SitTargetOffsetZ, " +
"SitTargetOrientW, SitTargetOrientX, " +
"SitTargetOrientY, SitTargetOrientZ, " +
"RegionUUID, CreatorID, " +
@ -181,19 +189,20 @@ namespace OpenSim.Data.MySQL
"AttachedPosY, AttachedPosZ, " +
"PhysicsShapeType, Density, GravityModifier, " +
"Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " +
"RotationAxisLocks, sopanims, sitactrange, pseudocrc" +
"RotationAxisLocks, sopanims" +
") values (" + "?UUID, " +
"?CreationDate, ?Name, ?Text, " +
"?Description, ?SitName, ?TouchName, " +
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
"?GroupMask, ?EveryoneMask, ?BaseMask, " +
"?PositionX, ?PositionY, ?PositionZ, " +
"?GroupPositionX, ?GroupPositionY, ?GroupPositionZ, " +
"?VelocityX, ?VelocityY, ?VelocityZ, "+
"?AngularVelocityX, ?AngularVelocityY, ?AngularVelocityZ, " +
"?AccelerationX, ?AccelerationY, ?AccelerationZ, " +
"?standtargetx, ?standtargety, ?standtargetz, " +
"?RotationX, ?RotationY, ?RotationZ, " +
"?GroupPositionX, ?GroupPositionY, " +
"?GroupPositionZ, ?VelocityX, " +
"?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
"?AngularVelocityY, ?AngularVelocityZ, " +
"?AccelerationX, ?AccelerationY, " +
"?AccelerationZ, ?RotationX, " +
"?RotationY, ?RotationZ, " +
"?RotationW, ?SitTargetOffsetX, " +
"?SitTargetOffsetY, ?SitTargetOffsetZ, " +
"?SitTargetOrientW, ?SitTargetOrientX, " +
@ -217,7 +226,7 @@ namespace OpenSim.Data.MySQL
"?AttachedPosY, ?AttachedPosZ, " +
"?PhysicsShapeType, ?Density, ?GravityModifier, " +
"?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," +
"?RotationAxisLocks, ?sopanims, ?sitactrange, ?pseudocrc)";
"?RotationAxisLocks, ?sopanims)";
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
@ -821,7 +830,7 @@ namespace OpenSim.Data.MySQL
"UserLookAtX, UserLookAtY, UserLookAtZ, " +
"AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia, " +
"SeeAVs, AnyAVSounds, GroupAVSounds, environment) values (" +
"SeeAVs, AnyAVSounds, GroupAVSounds) values (" +
"?UUID, ?RegionUUID, " +
"?LocalLandID, ?Bitmap, ?Name, ?Description, " +
"?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " +
@ -833,7 +842,7 @@ namespace OpenSim.Data.MySQL
"?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
"?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia, " +
"?SeeAVs, ?AnyAVSounds, ?GroupAVSounds, ?environment)";
"?SeeAVs, ?AnyAVSounds, ?GroupAVSounds)";
FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID);
@ -860,6 +869,107 @@ namespace OpenSim.Data.MySQL
}
}
public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
using(IDataReader result = ExecuteReader(cmd))
{
if(!result.Read())
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
// StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
}
}
dbcon.Close();
}
return nWP;
}
public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
{
RegionSettings rs = null;
@ -905,6 +1015,127 @@ namespace OpenSim.Data.MySQL
return rs;
}
public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "
+ "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "
+ "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "
+ "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "
+ "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "
+ "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "
+ "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "
+ "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "
+ "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "
+ "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "
+ "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "
+ "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "
+ "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "
+ "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "
+ "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "
+ "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "
+ "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "
+ "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "
+ "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "
+ "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "
+ "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "
+ "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "
+ "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "
+ "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "
+ "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"
;
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
}
dbcon.Close();
}
}
public virtual void RemoveRegionWindlightSettings(UUID regionID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
dbcon.Close();
}
}
#region RegionEnvironmentSettings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
@ -1000,7 +1231,7 @@ namespace OpenSim.Data.MySQL
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
"sunvectorz, loaded_creation_datetime, " +
"loaded_creation_id, map_tile_ID, block_search, casino, " +
"TelehubObject, parcel_tile_ID, cacheID) " +
"TelehubObject, parcel_tile_ID) " +
"values (?RegionUUID, ?BlockTerraform, " +
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
"?AllowLandResell, ?AllowLandJoinDivide, " +
@ -1017,7 +1248,7 @@ namespace OpenSim.Data.MySQL
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
"?LoadedCreationDateTime, ?LoadedCreationID, " +
"?TerrainImageID, ?block_search, ?casino, " +
"?TelehubObject, ?ParcelImageID, ?cacheID)";
"?TelehubObject, ?ParcelImageID)";
FillRegionSettingsCommand(cmd, rs);
ExecuteNonQuery(cmd);
@ -1121,57 +1352,49 @@ namespace OpenSim.Data.MySQL
// Vectors
prim.OffsetPosition = new Vector3(
(float)row["PositionX"],
(float)row["PositionY"],
(float)row["PositionZ"]
(float)(double)row["PositionX"],
(float)(double)row["PositionY"],
(float)(double)row["PositionZ"]
);
prim.GroupPosition = new Vector3(
(float)row["GroupPositionX"],
(float)row["GroupPositionY"],
(float)row["GroupPositionZ"]
(float)(double)row["GroupPositionX"],
(float)(double)row["GroupPositionY"],
(float)(double)row["GroupPositionZ"]
);
prim.Velocity = new Vector3(
(float)row["VelocityX"],
(float)row["VelocityY"],
(float)row["VelocityZ"]
(float)(double)row["VelocityX"],
(float)(double)row["VelocityY"],
(float)(double)row["VelocityZ"]
);
prim.AngularVelocity = new Vector3(
(float)row["AngularVelocityX"],
(float)row["AngularVelocityY"],
(float)row["AngularVelocityZ"]
(float)(double)row["AngularVelocityX"],
(float)(double)row["AngularVelocityY"],
(float)(double)row["AngularVelocityZ"]
);
prim.Acceleration = new Vector3(
(float)row["AccelerationX"],
(float)row["AccelerationY"],
(float)row["AccelerationZ"]
(float)(double)row["AccelerationX"],
(float)(double)row["AccelerationY"],
(float)(double)row["AccelerationZ"]
);
// quaternions
prim.RotationOffset = new Quaternion(
(float)row["RotationX"],
(float)row["RotationY"],
(float)row["RotationZ"],
(float)row["RotationW"]
(float)(double)row["RotationX"],
(float)(double)row["RotationY"],
(float)(double)row["RotationZ"],
(float)(double)row["RotationW"]
);
prim.SitTargetPositionLL = new Vector3(
(float)row["SitTargetOffsetX"],
(float)row["SitTargetOffsetY"],
(float)row["SitTargetOffsetZ"]
(float)(double)row["SitTargetOffsetX"],
(float)(double)row["SitTargetOffsetY"],
(float)(double)row["SitTargetOffsetZ"]
);
prim.SitTargetOrientationLL = new Quaternion(
(float)row["SitTargetOrientX"],
(float)row["SitTargetOrientY"],
(float)row["SitTargetOrientZ"],
(float)row["SitTargetOrientW"]
(float)(double)row["SitTargetOrientX"],
(float)(double)row["SitTargetOrientY"],
(float)(double)row["SitTargetOrientZ"],
(float)(double)row["SitTargetOrientW"]
);
prim.StandOffset = new Vector3(
(float)row["standtargetx"],
(float)row["standtargety"],
(float)row["standtargetz"]
);
prim.SitActiveRange = (float)row["sitactrange"];
prim.PayPrice[0] = (int)row["PayPrice"];
prim.PayPrice[1] = (int)row["PayButton1"];
prim.PayPrice[2] = (int)row["PayButton2"];
@ -1179,7 +1402,7 @@ namespace OpenSim.Data.MySQL
prim.PayPrice[4] = (int)row["PayButton4"];
prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString());
prim.SoundGain = (float)row["LoopedSoundGain"];
prim.SoundGain = (float)(double)row["LoopedSoundGain"];
if (prim.Sound != UUID.Zero)
prim.SoundFlags = 1; // If it's persisted at all, it's looped
else
@ -1191,21 +1414,21 @@ namespace OpenSim.Data.MySQL
prim.ParticleSystem = (byte[])row["ParticleSystem"];
prim.AngularVelocity = new Vector3(
(float)row["OmegaX"],
(float)row["OmegaY"],
(float)row["OmegaZ"]
(float)(double)row["OmegaX"],
(float)(double)row["OmegaY"],
(float)(double)row["OmegaZ"]
);
prim.SetCameraEyeOffset(new Vector3(
(float)row["CameraEyeOffsetX"],
(float)row["CameraEyeOffsetY"],
(float)row["CameraEyeOffsetZ"]
(float)(double)row["CameraEyeOffsetX"],
(float)(double)row["CameraEyeOffsetY"],
(float)(double)row["CameraEyeOffsetZ"]
));
prim.SetCameraAtOffset(new Vector3(
(float)row["CameraAtOffsetX"],
(float)row["CameraAtOffsetY"],
(float)row["CameraAtOffsetZ"]
(float)(double)row["CameraAtOffsetX"],
(float)(double)row["CameraAtOffsetY"],
(float)(double)row["CameraAtOffsetZ"]
));
prim.SetForceMouselook((sbyte)row["ForceMouselook"] != 0);
@ -1234,9 +1457,9 @@ namespace OpenSim.Data.MySQL
if (!(row["AttachedPosX"] is System.DBNull))
{
prim.AttachedPos = new Vector3(
(float)row["AttachedPosX"],
(float)row["AttachedPosY"],
(float)row["AttachedPosZ"]
(float)(double)row["AttachedPosX"],
(float)(double)row["AttachedPosY"],
(float)(double)row["AttachedPosZ"]
);
}
@ -1259,10 +1482,10 @@ namespace OpenSim.Data.MySQL
}
prim.PhysicsShapeType = (byte)Convert.ToInt32(row["PhysicsShapeType"].ToString());
prim.Density = (float)row["Density"];
prim.GravityModifier = (float)row["GravityModifier"];
prim.Friction = (float)row["Friction"];
prim.Restitution = (float)row["Restitution"];
prim.Density = (float)(double)row["Density"];
prim.GravityModifier = (float)(double)row["GravityModifier"];
prim.Friction = (float)(double)row["Friction"];
prim.Restitution = (float)(double)row["Restitution"];
prim.RotationAxisLocks = (byte)Convert.ToInt32(row["RotationAxisLocks"].ToString());
SOPVehicle vehicle = null;
@ -1292,12 +1515,6 @@ namespace OpenSim.Data.MySQL
prim.Animations = null;
}
prim.SitActiveRange = (float)row["sitactrange"];
int pseudocrc = (int)row["pseudocrc"];
if(pseudocrc != 0)
prim.PseudoCRC = pseudocrc;
return prim;
}
@ -1402,10 +1619,6 @@ namespace OpenSim.Data.MySQL
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
newSettings.Casino = Convert.ToBoolean(row["casino"]);
if (!(row["cacheID"] is DBNull))
newSettings.CacheID = DBGuid.FromDB(row["cacheID"]);
return newSettings;
}
@ -1489,34 +1702,6 @@ namespace OpenSim.Data.MySQL
if (!(row["GroupAVSounds"] is System.DBNull))
newData.GroupAVSounds = Convert.ToInt32(row["GroupAVSounds"]) != 0 ? true : false;
if (row["environment"] is DBNull)
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
else
{
string env = (string)row["environment"];
if(string.IsNullOrEmpty(env))
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
else
{
try
{
ViewerEnvironment VEnv = ViewerEnvironment.FromOSDString(env);
newData.Environment = VEnv;
newData.EnvironmentVersion = VEnv.version;
}
catch
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
}
}
return newData;
}
@ -1571,43 +1756,38 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask);
cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask);
// vectors
cmd.Parameters.AddWithValue("PositionX", prim.OffsetPosition.X);
cmd.Parameters.AddWithValue("PositionY", prim.OffsetPosition.Y);
cmd.Parameters.AddWithValue("PositionZ", prim.OffsetPosition.Z);
cmd.Parameters.AddWithValue("GroupPositionX", prim.GroupPosition.X);
cmd.Parameters.AddWithValue("GroupPositionY", prim.GroupPosition.Y);
cmd.Parameters.AddWithValue("GroupPositionZ", prim.GroupPosition.Z);
cmd.Parameters.AddWithValue("VelocityX", prim.Velocity.X);
cmd.Parameters.AddWithValue("VelocityY", prim.Velocity.Y);
cmd.Parameters.AddWithValue("VelocityZ", prim.Velocity.Z);
cmd.Parameters.AddWithValue("AngularVelocityX", prim.AngularVelocity.X);
cmd.Parameters.AddWithValue("AngularVelocityY", prim.AngularVelocity.Y);
cmd.Parameters.AddWithValue("AngularVelocityZ", prim.AngularVelocity.Z);
cmd.Parameters.AddWithValue("AccelerationX", prim.Acceleration.X);
cmd.Parameters.AddWithValue("AccelerationY", prim.Acceleration.Y);
cmd.Parameters.AddWithValue("AccelerationZ", prim.Acceleration.Z);
cmd.Parameters.AddWithValue("standtargetx", prim.StandOffset.X);
cmd.Parameters.AddWithValue("standtargety", prim.StandOffset.Y);
cmd.Parameters.AddWithValue("standtargetz", prim.StandOffset.Z);
cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X);
cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y);
cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z);
cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X);
cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y);
cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z);
cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X);
cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y);
cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z);
cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X);
cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y);
cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z);
cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X);
cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y);
cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z);
// quaternions
cmd.Parameters.AddWithValue("RotationX", prim.RotationOffset.X);
cmd.Parameters.AddWithValue("RotationY", prim.RotationOffset.Y);
cmd.Parameters.AddWithValue("RotationZ", prim.RotationOffset.Z);
cmd.Parameters.AddWithValue("RotationW", prim.RotationOffset.W);
cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X);
cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y);
cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z);
cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W);
// Sit target
Vector3 sitTargetPos = prim.SitTargetPositionLL;
cmd.Parameters.AddWithValue("SitTargetOffsetX", sitTargetPos.X);
cmd.Parameters.AddWithValue("SitTargetOffsetY", sitTargetPos.Y);
cmd.Parameters.AddWithValue("SitTargetOffsetZ", sitTargetPos.Z);
cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X);
cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y);
cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z);
Quaternion sitTargetOrient = prim.SitTargetOrientationLL;
cmd.Parameters.AddWithValue("SitTargetOrientW", sitTargetOrient.W);
cmd.Parameters.AddWithValue("SitTargetOrientX", sitTargetOrient.X);
cmd.Parameters.AddWithValue("SitTargetOrientY", sitTargetOrient.Y);
cmd.Parameters.AddWithValue("SitTargetOrientZ", sitTargetOrient.Z);
cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W);
cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X);
cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y);
cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z);
cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]);
cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]);
@ -1618,7 +1798,7 @@ namespace OpenSim.Data.MySQL
if ((prim.SoundFlags & 1) != 0) // Looped
{
cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString());
cmd.Parameters.AddWithValue("LoopedSoundGain", (float)prim.SoundGain);
cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain);
}
else
{
@ -1629,17 +1809,17 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation);
cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem);
cmd.Parameters.AddWithValue("OmegaX", prim.AngularVelocity.X);
cmd.Parameters.AddWithValue("OmegaY", prim.AngularVelocity.Y);
cmd.Parameters.AddWithValue("OmegaZ", prim.AngularVelocity.Z);
cmd.Parameters.AddWithValue("OmegaX", (double)prim.AngularVelocity.X);
cmd.Parameters.AddWithValue("OmegaY", (double)prim.AngularVelocity.Y);
cmd.Parameters.AddWithValue("OmegaZ", (double)prim.AngularVelocity.Z);
cmd.Parameters.AddWithValue("CameraEyeOffsetX", prim.GetCameraEyeOffset().X);
cmd.Parameters.AddWithValue("CameraEyeOffsetY", prim.GetCameraEyeOffset().Y);
cmd.Parameters.AddWithValue("CameraEyeOffsetZ", prim.GetCameraEyeOffset().Z);
cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X);
cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y);
cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z);
cmd.Parameters.AddWithValue("CameraAtOffsetX", prim.GetCameraAtOffset().X);
cmd.Parameters.AddWithValue("CameraAtOffsetY", prim.GetCameraAtOffset().Y);
cmd.Parameters.AddWithValue("CameraAtOffsetZ", prim.GetCameraAtOffset().Z);
cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X);
cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y);
cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z);
if (prim.GetForceMouselook())
cmd.Parameters.AddWithValue("ForceMouselook", 1);
@ -1683,9 +1863,9 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
if (prim.AttachedPos != null)
{
cmd.Parameters.AddWithValue("AttachedPosX", prim.AttachedPos.X);
cmd.Parameters.AddWithValue("AttachedPosY", prim.AttachedPos.Y);
cmd.Parameters.AddWithValue("AttachedPosZ", prim.AttachedPos.Z);
cmd.Parameters.AddWithValue("AttachedPosX", (double)prim.AttachedPos.X);
cmd.Parameters.AddWithValue("AttachedPosY", (double)prim.AttachedPos.Y);
cmd.Parameters.AddWithValue("AttachedPosZ", (double)prim.AttachedPos.Z);
}
if (prim.KeyframeMotion != null)
@ -1709,19 +1889,16 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("DynAttrs", null);
cmd.Parameters.AddWithValue("PhysicsShapeType", prim.PhysicsShapeType);
cmd.Parameters.AddWithValue("Density", prim.Density);
cmd.Parameters.AddWithValue("GravityModifier", prim.GravityModifier);
cmd.Parameters.AddWithValue("Friction", prim.Friction);
cmd.Parameters.AddWithValue("Restitution", prim.Restitution);
cmd.Parameters.AddWithValue("Density", (double)prim.Density);
cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier);
cmd.Parameters.AddWithValue("Friction", (double)prim.Friction);
cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution);
cmd.Parameters.AddWithValue("RotationAxisLocks", prim.RotationAxisLocks);
if (prim.Animations!= null)
cmd.Parameters.AddWithValue("sopanims", prim.SerializeAnimations());
else
cmd.Parameters.AddWithValue("sopanims", null);
cmd.Parameters.AddWithValue("sitactrange", prim.SitActiveRange);
cmd.Parameters.AddWithValue("pseudocrc", prim.PseudoCRC);
}
/// <summary>
@ -1805,7 +1982,6 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID);
cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject);
cmd.Parameters.AddWithValue("cacheID", settings.CacheID);
}
/// <summary>
@ -1863,19 +2039,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("SeeAVs", land.SeeAVs ? 1 : 0);
cmd.Parameters.AddWithValue("AnyAVSounds", land.AnyAVSounds ? 1 : 0);
cmd.Parameters.AddWithValue("GroupAVSounds", land.GroupAVSounds ? 1 : 0);
if (land.Environment == null)
cmd.Parameters.AddWithValue("environment", "");
else
{
try
{
cmd.Parameters.AddWithValue("environment", ViewerEnvironment.ToOSDString(land.Environment));
}
catch
{
cmd.Parameters.AddWithValue("environment", "");
}
}
}
/// <summary>

View File

@ -76,8 +76,3 @@ ALTER TABLE `estateban`
ADD COLUMN `banTime` int(11) NOT NULL DEFAULT 0;
COMMIT;
:VERSION 36
BEGIN;
ALTER TABLE `estate_settings`
ADD COLUMN `AllowEnviromentOverride` tinyint(4) NOT NULL DEFAULT '0';
COMMIT;

View File

@ -474,79 +474,3 @@ BEGIN;
ALTER TABLE `prims` ADD COLUMN `sopanims` blob default NULL;
COMMIT;
:VERSION 59 #----- Add standtarget and sit range
BEGIN;
ALTER TABLE `prims`
ADD COLUMN `standtargetx` float DEFAULT '0.0',
ADD COLUMN `standtargety` float DEFAULT '0.0',
ADD COLUMN `standtargetz` float DEFAULT '0.0',
ADD COLUMN `sitactrange` float DEFAULT '0.0';
COMMIT;
:VERSION 60 #----- don't store float on double
BEGIN;
ALTER TABLE `prims`
MODIFY `PositionX` float DEFAULT '0.0',
MODIFY `PositionY` float DEFAULT '0.0',
MODIFY `PositionZ` float DEFAULT '0.0',
MODIFY `GroupPositionX` float DEFAULT '0.0',
MODIFY `GroupPositionY` float DEFAULT '0.0',
MODIFY `GroupPositionZ` float DEFAULT '0.0',
MODIFY `VelocityX` float DEFAULT '0.0',
MODIFY `VelocityY` float DEFAULT '0.0',
MODIFY `VelocityZ` float DEFAULT '0.0',
MODIFY `AngularVelocityX` float DEFAULT '0.0',
MODIFY `AngularVelocityY` float DEFAULT '0.0',
MODIFY `AngularVelocityZ` float DEFAULT '0.0',
MODIFY `AccelerationX` float DEFAULT '0.0',
MODIFY `AccelerationY` float DEFAULT '0.0',
MODIFY `AccelerationZ` float DEFAULT '0.0',
MODIFY `RotationX` float DEFAULT '0.0',
MODIFY `RotationY` float DEFAULT '0.0',
MODIFY `RotationZ` float DEFAULT '0.0',
MODIFY `RotationW` float DEFAULT '0.0',
MODIFY `SitTargetOffsetX` float DEFAULT '0.0',
MODIFY `SitTargetOffsetY` float DEFAULT '0.0',
MODIFY `SitTargetOffsetZ` float DEFAULT '0.0',
MODIFY `SitTargetOrientX` float DEFAULT '0.0',
MODIFY `SitTargetOrientY` float DEFAULT '0.0',
MODIFY `SitTargetOrientZ` float DEFAULT '0.0',
MODIFY `SitTargetOrientW` float DEFAULT '0.0',
MODIFY `OmegaX` float DEFAULT '0.0',
MODIFY `OmegaY` float DEFAULT '0.0',
MODIFY `OmegaZ` float DEFAULT '0.0',
MODIFY `CameraEyeOffsetX` float DEFAULT '0.0',
MODIFY `CameraEyeOffsetY` float DEFAULT '0.0',
MODIFY `CameraEyeOffsetZ` float DEFAULT '0.0',
MODIFY `CameraAtOffsetX` float DEFAULT '0.0',
MODIFY `CameraAtOffsetY` float DEFAULT '0.0',
MODIFY `CameraAtOffsetZ` float DEFAULT '0.0',
MODIFY `Density` float DEFAULT '1000.0',
MODIFY `GravityModifier` float DEFAULT '1.0',
MODIFY `Friction` float DEFAULT '0.6',
MODIFY `Restitution` float DEFAULT '0.5',
MODIFY `AttachedPosX` float DEFAULT '0',
MODIFY `AttachedPosY` float DEFAULT '0',
MODIFY `AttachedPosZ` float DEFAULT '0',
MODIFY `LoopedSoundGain` float DEFAULT '0';
COMMIT;
:VERSION 61 #----- Add pseudo CRC and region cache id
BEGIN;
ALTER TABLE `prims` ADD COLUMN `pseudocrc` int DEFAULT '0';
ALTER TABLE `regionsettings` ADD COLUMN `cacheID` char(36) DEFAULT NULL;
COMMIT;
:VERSION 62 #----- increase size of environment settings
BEGIN;
ALTER TABLE `regionenvironment` MODIFY `llsd_settings` MEDIUMTEXT;
COMMIT;
:VERSION 63 #----- parcel environment store
BEGIN;
ALTER TABLE `land` ADD COLUMN `environment` MEDIUMTEXT default NULL;
COMMIT;

View File

@ -354,9 +354,7 @@ namespace OpenSim.Data.PGSQL
""PassCollisions"" = :PassCollisions, ""RotationAxisLocks"" = :RotationAxisLocks, ""RezzerID"" = :RezzerID,
""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches,
""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs, ""Vehicle"" = :Vehicle,
""PhysInertia"" = :PhysInertia, ""standtargetx"" =:standtargetx, ""standtargety"" =:standtargety, ""standtargetz"" =:standtargetz,
""sitactrange"" =:sitactrange, ""pseudocrc"" = :pseudocrc
""PhysInertia"" = :PhysInertia
WHERE ""UUID"" = :UUID ;
INSERT INTO
@ -370,8 +368,7 @@ namespace OpenSim.Data.PGSQL
""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"",
""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"",
""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"",
""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""Vehicle"", ""PhysInertia"",
""standtargetx"", ""standtargety"", ""standtargetz"", ""sitactrange"", ""pseudocrc""
""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""Vehicle"", ""PhysInertia""
) Select
:UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask,
:EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX,
@ -382,8 +379,7 @@ namespace OpenSim.Data.PGSQL
:OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ,
:ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA,
:ParticleSystem, :ClickAction, :Material, :CollisionSound, :CollisionSoundVolume, :PassTouches, :LinkNumber, :MediaURL, :DynAttrs,
:PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution, :PassCollisions, :RotationAxisLocks, :RezzerID, :Vehicle, :PhysInertia,
:standtargetx, :standtargety, :standtargetz,:sitactrange, :pseudocrc
:PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution, :PassCollisions, :RotationAxisLocks, :RezzerID, :Vehicle, :PhysInertia
where not EXISTS (SELECT ""UUID"" FROM prims WHERE ""UUID"" = :UUID);
";
@ -770,14 +766,13 @@ namespace OpenSim.Data.PGSQL
(""UUID"",""RegionUUID"",""LocalLandID"",""Bitmap"",""Name"",""Description"",""OwnerUUID"",""IsGroupOwned"",""Area"",""AuctionID"",""Category"",""ClaimDate"",""ClaimPrice"",
""GroupUUID"",""SalePrice"",""LandStatus"",""LandFlags"",""LandingType"",""MediaAutoScale"",""MediaTextureUUID"",""MediaURL"",""MusicURL"",""PassHours"",""PassPrice"",
""SnapshotUUID"",""UserLocationX"",""UserLocationY"",""UserLocationZ"",""UserLookAtX"",""UserLookAtY"",""UserLookAtZ"",""AuthbuyerID"",""OtherCleanTime"",""Dwell"",
""MediaType"",""MediaDescription"",""MediaSize"",""MediaLoop"",""ObscureMusic"",""ObscureMedia"",""SeeAVs"",""AnyAVSounds"",""GroupAVSounds"",
""environment"")
""MediaType"",""MediaDescription"",""MediaSize"",""MediaLoop"",""ObscureMusic"",""ObscureMedia"",""SeeAVs"",""AnyAVSounds"",""GroupAVSounds"")
VALUES
(:UUID,:RegionUUID,:LocalLandID,:Bitmap,:Name,:Description,:OwnerUUID,:IsGroupOwned,:Area,:AuctionID,:Category,:ClaimDate,:ClaimPrice,
:GroupUUID,:SalePrice,:LandStatus,:LandFlags,:LandingType,:MediaAutoScale,:MediaTextureUUID,:MediaURL,:MusicURL,:PassHours,:PassPrice,
:SnapshotUUID,:UserLocationX,:UserLocationY,:UserLocationZ,:UserLookAtX,:UserLookAtY,:UserLookAtZ,:AuthbuyerID,:OtherCleanTime,:Dwell,
:MediaType,:MediaDescription,:MediaWidth::text || ',' || :MediaHeight::text,:MediaLoop,:ObscureMusic,:ObscureMedia,:SeeAVs::int::smallint,
:AnyAVSounds::int::smallint,:GroupAVSounds::int::smallint,:environment)";
:AnyAVSounds::int::smallint,:GroupAVSounds::int::smallint)";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
@ -826,6 +821,477 @@ namespace OpenSim.Data.PGSQL
cmd.ExecuteNonQuery();
}
}
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
string sql = @"select * from regionwindlight where ""region_id"" = :regionID";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("regionID", regionUUID.ToString() ));
conn.Open();
using (NpgsqlDataReader result = cmd.ExecuteReader())
{
if (!result.Read())
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
}
}
return nWP;
}
public void RemoveRegionWindlightSettings(UUID regionID)
{
string sql = @"delete from regionwindlight where ""region_id"" = :region_id";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
conn.Open();
cmd.Parameters.Add(_Database.CreateParameter("region_id", regionID.ToString()));
cmd.ExecuteNonQuery();
}
}
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
string sql = @"select region_id from regionwindlight where ""region_id"" = :region_id limit 1;";
bool exists = false;
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
{
conn.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID.ToString() ));
NpgsqlDataReader dr = cmd.ExecuteReader();
exists = dr.Read();
}
}
if (exists)
{
RemoveRegionWindlightSettings(wl.regionID);
}
// sql insert
sql = @"INSERT INTO regionwindlight
(region_id
,water_color_r
,water_color_g
,water_color_b
,water_fog_density_exponent
,underwater_fog_modifier
,reflection_wavelet_scale_1
,reflection_wavelet_scale_2
,reflection_wavelet_scale_3
,fresnel_scale
,fresnel_offset
,refract_scale_above
,refract_scale_below
,blur_multiplier
,big_wave_direction_x
,big_wave_direction_y
,little_wave_direction_x
,little_wave_direction_y
,normal_map_texture
,horizon_r
,horizon_g
,horizon_b
,horizon_i
,haze_horizon
,blue_density_r
,blue_density_g
,blue_density_b
,blue_density_i
,haze_density
,density_multiplier
,distance_multiplier
,max_altitude
,sun_moon_color_r
,sun_moon_color_g
,sun_moon_color_b
,sun_moon_color_i
,sun_moon_position
,ambient_r
,ambient_g
,ambient_b
,ambient_i
,east_angle
,sun_glow_focus
,sun_glow_size
,scene_gamma
,star_brightness
,cloud_color_r
,cloud_color_g
,cloud_color_b
,cloud_color_i
,cloud_x
,cloud_y
,cloud_density
,cloud_coverage
,cloud_scale
,cloud_detail_x
,cloud_detail_y
,cloud_detail_density
,cloud_scroll_x
,cloud_scroll_x_lock
,cloud_scroll_y
,cloud_scroll_y_lock
,draw_classic_clouds)
VALUES
(:region_id
,:water_color_r
,:water_color_g
,:water_color_b
,:water_fog_density_exponent
,:underwater_fog_modifier
,:reflection_wavelet_scale_1
,:reflection_wavelet_scale_2
,:reflection_wavelet_scale_3
,:fresnel_scale
,:fresnel_offset
,:refract_scale_above
,:refract_scale_below
,:blur_multiplier
,:big_wave_direction_x
,:big_wave_direction_y
,:little_wave_direction_x
,:little_wave_direction_y
,:normal_map_texture
,:horizon_r
,:horizon_g
,:horizon_b
,:horizon_i
,:haze_horizon
,:blue_density_r
,:blue_density_g
,:blue_density_b
,:blue_density_i
,:haze_density
,:density_multiplier
,:distance_multiplier
,:max_altitude
,:sun_moon_color_r
,:sun_moon_color_g
,:sun_moon_color_b
,:sun_moon_color_i
,:sun_moon_position
,:ambient_r
,:ambient_g
,:ambient_b
,:ambient_i
,:east_angle
,:sun_glow_focus
,:sun_glow_size
,:scene_gamma
,:star_brightness
,:cloud_color_r
,:cloud_color_g
,:cloud_color_b
,:cloud_color_i
,:cloud_x
,:cloud_y
,:cloud_density
,:cloud_coverage
,:cloud_scale
,:cloud_detail_x
,:cloud_detail_y
,:cloud_detail_density
,:cloud_scroll_x
,:cloud_scroll_x_lock
,:cloud_scroll_y
,:cloud_scroll_y_lock
,:draw_classic_clouds);";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
{
conn.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
{
cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID.ToString()));
cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X));
cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y));
cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z));
cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent));
cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier));
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X));
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y));
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z));
cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale));
cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset));
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove));
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow));
cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier));
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X));
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y));
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X));
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y));
cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture.ToString()));
cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X));
cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y));
cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z));
cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W));
cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z));
cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W));
cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity));
cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier));
cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier));
cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W));
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition));
cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X));
cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y));
cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z));
cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W));
cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle));
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus));
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize));
cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma));
cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z));
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W));
cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X));
cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y));
cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z));
cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale));
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X));
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y));
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY));
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock));
cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds));
cmd.ExecuteNonQuery();
}
}
#region update
// }
// else
// {
// // sql update
// sql = @"UPDATE [OpenSim].[dbo].[regionwindlight]
// SET [region_id] = @region_id
// ,[water_color_r] = @water_color_r
// ,[water_color_g] = @water_color_g
// ,[water_color_b] = @water_color_b
// ,[water_fog_density_exponent] = @water_fog_density_exponent
// ,[underwater_fog_modifier] = @underwater_fog_modifier
// ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1
// ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2
// ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3
// ,[fresnel_scale] = @fresnel_scale
// ,[fresnel_offset] = @fresnel_offset
// ,[refract_scale_above] = @refract_scale_above
// ,[refract_scale_below] = @refract_scale_below
// ,[blur_multiplier] = @blur_multiplier
// ,[big_wave_direction_x] = @big_wave_direction_x
// ,[big_wave_direction_y] = @big_wave_direction_y
// ,[little_wave_direction_x] = @little_wave_direction_x
// ,[little_wave_direction_y] = @little_wave_direction_y
// ,[normal_map_texture] = @normal_map_texture
// ,[horizon_r] = @horizon_r
// ,[horizon_g] = @horizon_g
// ,[horizon_b] = @horizon_b
// ,[horizon_i] = @horizon_i
// ,[haze_horizon] = @haze_horizon
// ,[blue_density_r] = @blue_density_r
// ,[blue_density_g] = @blue_density_g
// ,[blue_density_b] = @blue_density_b
// ,[blue_density_i] = @blue_density_i
// ,[haze_density] = @haze_density
// ,[density_multiplier] = @density_multiplier
// ,[distance_multiplier] = @distance_multiplier
// ,[max_altitude] = @max_altitude
// ,[sun_moon_color_r] = @sun_moon_color_r
// ,[sun_moon_color_g] = @sun_moon_color_g
// ,[sun_moon_color_b] = @sun_moon_color_b
// ,[sun_moon_color_i] = @sun_moon_color_i
// ,[sun_moon_position] = @sun_moon_position
// ,[ambient_r] = @ambient_r
// ,[ambient_g] = @ambient_g
// ,[ambient_b] = @ambient_b
// ,[ambient_i] = @ambient_i
// ,[east_angle] = @east_angle
// ,[sun_glow_focus] = @sun_glow_focus
// ,[sun_glow_size] = @sun_glow_size
// ,[scene_gamma] = @scene_gamma
// ,[star_brightness] = @star_brightness
// ,[cloud_color_r] = @cloud_color_r
// ,[cloud_color_g] = @cloud_color_g
// ,[cloud_color_b] = @cloud_color_b
// ,[cloud_color_i] = @cloud_color_i
// ,[cloud_x] = @cloud_x
// ,[cloud_y] = @cloud_y
// ,[cloud_density] = @cloud_density
// ,[cloud_coverage] = @cloud_coverage
// ,[cloud_scale] = @cloud_scale
// ,[cloud_detail_x] = @cloud_detail_x
// ,[cloud_detail_y] = @cloud_detail_y
// ,[cloud_detail_density] = @cloud_detail_density
// ,[cloud_scroll_x] = @cloud_scroll_x
// ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock
// ,[cloud_scroll_y] = @cloud_scroll_y
// ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock
// ,[draw_classic_clouds] = @draw_classic_clouds
// WHERE region_id = @region_id";
// using (SqlConnection conn = new SqlConnection(m_connectionString))
// {
// conn.Open();
// using (SqlCommand cmd = new SqlCommand(sql, conn))
// {
// cmd.Parameters.AddWithValue("region_id", wl.regionID);
// cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
// cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
// cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
// cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
// cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
// cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
// cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
// cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
// cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
// cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
// cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
// cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
// cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
// cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
// cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
// cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
// cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
// cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
// cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
// cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
// cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
// cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
// cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
// cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
// cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
// cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
// cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
// cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
// cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
// cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
// cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
// cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
// cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
// cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
// cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
// cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
// cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
// cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
// cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
// cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
// cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
// cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
// cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
// cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
// cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
// cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
// cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
// cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
// cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
// cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
// cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
// cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
// cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
// cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
// cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
// cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
// cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
// cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
// cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
// cmd.ExecuteNonQuery();
// }
// }
// }
#endregion
}
#region Environment Settings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
@ -966,7 +1432,7 @@ namespace OpenSim.Data.PGSQL
,terrain_lower_limit = :terrain_lower_limit ,use_estate_sun = :use_estate_sun ,fixed_sun = :fixed_sun ,sun_position = :sun_position
,covenant = :covenant ,covenant_datetime = :covenant_datetime, sunvectorx = :sunvectorx, sunvectory = :sunvectory, sunvectorz = :sunvectorz,
""Sandbox"" = :Sandbox, loaded_creation_datetime = :loaded_creation_datetime, loaded_creation_id = :loaded_creation_id, ""map_tile_ID"" = :TerrainImageID,
""TelehubObject"" = :telehubobject, ""parcel_tile_ID"" = :ParcelImageID, ""cacheID"" = :cacheID
""TelehubObject"" = :telehubobject, ""parcel_tile_ID"" = :ParcelImageID
WHERE ""regionUUID"" = :regionUUID";
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
@ -1081,8 +1547,6 @@ namespace OpenSim.Data.PGSQL
newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]);
newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]);
if (!(row["cacheID"] is DBNull))
newSettings.CacheID = new UUID((Guid)row["cacheID"]);
return newSettings;
}
@ -1138,6 +1602,7 @@ namespace OpenSim.Data.PGSQL
newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
newData.Dwell = Convert.ToSingle(row["Dwell"]);
try
{
newData.UserLocation =
@ -1167,35 +1632,6 @@ namespace OpenSim.Data.PGSQL
newData.AnyAVSounds = Convert.ToBoolean(row["AnyAVSounds"]);
newData.GroupAVSounds = Convert.ToBoolean(row["GroupAVSounds"]);
if (row["environment"] is DBNull)
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
else
{
string env = (string)row["environment"];
if (string.IsNullOrEmpty(env))
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
else
{
try
{
ViewerEnvironment VEnv = ViewerEnvironment.FromOSDString(env);
newData.Environment = VEnv;
newData.EnvironmentVersion = VEnv.version;
}
catch
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
}
}
return newData;
}
@ -1256,9 +1692,9 @@ namespace OpenSim.Data.PGSQL
prim.BaseMask = Convert.ToUInt32(primRow["BaseMask"]);
// vectors
prim.OffsetPosition = new Vector3(
Convert.ToSingle(primRow["PositionX"]),
Convert.ToSingle(primRow["PositionY"]),
Convert.ToSingle(primRow["PositionZ"]));
Convert.ToSingle(primRow["PositionX"]),
Convert.ToSingle(primRow["PositionY"]),
Convert.ToSingle(primRow["PositionZ"]));
prim.GroupPosition = new Vector3(
Convert.ToSingle(primRow["GroupPositionX"]),
@ -1271,9 +1707,9 @@ namespace OpenSim.Data.PGSQL
Convert.ToSingle(primRow["VelocityZ"]));
prim.AngularVelocity = new Vector3(
Convert.ToSingle(primRow["AngularVelocityX"]),
Convert.ToSingle(primRow["AngularVelocityY"]),
Convert.ToSingle(primRow["AngularVelocityZ"]));
Convert.ToSingle(primRow["AngularVelocityX"]),
Convert.ToSingle(primRow["AngularVelocityY"]),
Convert.ToSingle(primRow["AngularVelocityZ"]));
prim.Acceleration = new Vector3(
Convert.ToSingle(primRow["AccelerationX"]),
@ -1292,20 +1728,12 @@ namespace OpenSim.Data.PGSQL
Convert.ToSingle(primRow["SitTargetOffsetY"]),
Convert.ToSingle(primRow["SitTargetOffsetZ"]));
prim.SitTargetOrientationLL = new Quaternion(
Convert.ToSingle(primRow["SitTargetOrientX"]),
Convert.ToSingle(primRow["SitTargetOrientY"]),
Convert.ToSingle(primRow["SitTargetOrientZ"]),
Convert.ToSingle(primRow["SitTargetOrientW"]));
prim.StandOffset = new Vector3(
Convert.ToSingle(primRow["standtargetx"]),
Convert.ToSingle(primRow["standtargety"]),
Convert.ToSingle(primRow["standtargetz"]));
prim.SitActiveRange = Convert.ToSingle(primRow["sitactrange"]);
prim.PayPrice[0] = Convert.ToInt32(primRow["PayPrice"]);
prim.PayPrice[1] = Convert.ToInt32(primRow["PayButton1"]);
prim.PayPrice[2] = Convert.ToInt32(primRow["PayButton2"]);
@ -1394,10 +1822,6 @@ namespace OpenSim.Data.PGSQL
pdata = PhysicsInertiaData.FromXml2(primRow["PhysInertia"].ToString());
prim.PhysicsInertia = pdata;
int pseudocrc = Convert.ToInt32(primRow["pseudocrc"]);
if(pseudocrc != 0)
prim.PseudoCRC = pseudocrc;
return prim;
}
@ -1584,8 +2008,6 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID));
parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject));
parameters.Add(_Database.CreateParameter("cacheID", settings.CacheID));
return parameters.ToArray();
}
@ -1647,20 +2069,6 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("AnyAVSounds", land.AnyAVSounds));
parameters.Add(_Database.CreateParameter("GroupAVSounds", land.GroupAVSounds));
if (land.Environment == null)
parameters.Add(_Database.CreateParameter("environment", ""));
else
{
try
{
parameters.Add(_Database.CreateParameter("environment", ViewerEnvironment.ToOSDString(land.Environment)));
}
catch
{
parameters.Add(_Database.CreateParameter("environment", ""));
}
}
return parameters.ToArray();
}
@ -1754,13 +2162,6 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("SitTargetOrientY", sitTargetOrient.Y));
parameters.Add(_Database.CreateParameter("SitTargetOrientZ", sitTargetOrient.Z));
Vector3 standTargetPos = prim.StandOffset;
parameters.Add(_Database.CreateParameter("standtargetx", standTargetPos.X));
parameters.Add(_Database.CreateParameter("standtargety", standTargetPos.Y));
parameters.Add(_Database.CreateParameter("standtargetz", standTargetPos.Z));
parameters.Add(_Database.CreateParameter("sitactrange", prim.SitActiveRange));
parameters.Add(_Database.CreateParameter("PayPrice", prim.PayPrice[0]));
parameters.Add(_Database.CreateParameter("PayButton1", prim.PayPrice[1]));
parameters.Add(_Database.CreateParameter("PayButton2", prim.PayPrice[2]));
@ -1859,8 +2260,6 @@ namespace OpenSim.Data.PGSQL
parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution));
parameters.Add(_Database.CreateParameter("RotationAxisLocks", prim.RotationAxisLocks));
parameters.Add(_Database.CreateParameter("pseudocrc", prim.PseudoCRC));
return parameters.ToArray();
}

View File

@ -133,9 +133,3 @@ ALTER TABLE "public"."estateban"
ADD COLUMN "banningUUID" uuid NOT NULL,
ADD COLUMN "banTime" int4 NOT NULL DEFAULT 0;
COMMIT;
:VERSION 15
BEGIN TRANSACTION;
ALTER TABLE "public"."estate_settings"
ADD COLUMN "AllowEnviromentOverride" bool NOT NULL;
COMMIT;

View File

@ -1232,26 +1232,3 @@ BEGIN TRANSACTION;
ALTER TABLE prims ADD "Vehicle" TEXT;
COMMIT;
:VERSION 49 #----- Add standtarget and sit range
BEGIN;
ALTER TABLE `prims`
ADD COLUMN `standtargetx` real DEFAULT '0.0',
ADD COLUMN `standtargety` real DEFAULT '0.0',
ADD COLUMN `standtargetz` real DEFAULT '0.0',
ADD COLUMN `sitactrange` real DEFAULT '0.0';
COMMIT;
:VERSION 50 #----- Add pseudo CRC and region cache id
BEGIN;
ALTER TABLE `prims` ADD COLUMN `pseudocrc` integer DEFAULT '0';
ALTER TABLE `regionsettings` ADD COLUMN `cacheID` uuid DEFAULT NULL;
COMMIT;
:VERSION 51 #----- parcel environment store
BEGIN;
ALTER TABLE `land` ADD COLUMN `environment` varchar default NULL;
COMMIT;

View File

@ -74,10 +74,4 @@ ALTER TABLE `estateban` ADD COLUMN `banningUUID` varchar(36) NOT NULL DEFAULT '0
ALTER TABLE `estateban` ADD COLUMN `banTime` integer NOT NULL DEFAULT 0;
COMMIT;
:VERSION 12
BEGIN;
ALTER TABLE `estate_settings`
ADD COLUMN `AllowEnviromentOverride` tinyint not null default 0;
COMMIT;

View File

@ -183,14 +183,14 @@ CREATE TABLE IF NOT EXISTS land(
UserLookAtY float,
UserLookAtZ float,
AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000',
OtherCleanTime INTEGER NOT NULL default 0,
Dwell INTEGER NOT NULL default 0,
`MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none',
`MediaDescription` VARCHAR(255) NOT NULL DEFAULT '',
`MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0',
`MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE,
`ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE,
`ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE);
OtherCleanTime INTEGER NOT NULL default 0,
Dwell INTEGER NOT NULL default 0,
`MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none',
`MediaDescription` VARCHAR(255) NOT NULL DEFAULT '',
`MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0',
`MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE,
`ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE,
`ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE);
CREATE TABLE IF NOT EXISTS landaccesslist(
LandUUID varchar(255),
@ -377,25 +377,3 @@ COMMIT;
BEGIN;
ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL;
COMMIT;
:VERSION 37 #----- Add standtarget and sit range
BEGIN;
ALTER TABLE `prims` ADD COLUMN `standtargetx` float NOT NULL DEFAULT '0.0';
ALTER TABLE `prims` ADD COLUMN `standtargety` float NOT NULL DEFAULT '0.0';
ALTER TABLE `prims` ADD COLUMN `standtargetz` float NOT NULL DEFAULT '0.0';
ALTER TABLE `prims` ADD COLUMN `sitactrange` float NOT NULL DEFAULT '0.0';
COMMIT;
:VERSION 38 #----- Add pseudo CRC and region cache id
BEGIN;
ALTER TABLE `prims` ADD COLUMN `pseudocrc` integer DEFAULT '0';
ALTER TABLE `regionsettings` ADD COLUMN `cacheID` char(36) DEFAULT NULL;
COMMIT;
:VERSION 39 #----- parcel environment store
BEGIN;
ALTER TABLE `land` ADD COLUMN `environment` TEXT default NULL;
COMMIT;

View File

@ -186,10 +186,13 @@ namespace OpenSim.Data.SQLite
private void DoCreate(EstateSettings es)
{
List<string> names = new List<string>(FieldList);
names.Remove("EstateID");
IDataReader r = null;
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
names.Remove("EstateID");
string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
cmd.CommandText = sql;
@ -214,12 +217,17 @@ namespace OpenSim.Data.SQLite
cmd.CommandText = "select LAST_INSERT_ROWID() as id";
cmd.Parameters.Clear();
using(IDataReader r = cmd.ExecuteReader())
{
r.Read();
es.EstateID = Convert.ToUInt32(r["id"]);
}
r = cmd.ExecuteReader();
}
r.Read();
es.EstateID = Convert.ToUInt32(r["id"]);
r.Close();
es.Save();
}
public void StoreEstateSettings(EstateSettings es)
@ -232,10 +240,11 @@ namespace OpenSim.Data.SQLite
foreach (string f in fields)
terms.Add(f+" = :"+f);
string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID";
using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "update estate_settings set " + String.Join(", ", terms.ToArray()) + " where EstateID = :EstateID"; ;
cmd.Parameters.AddWithValue(":EstateID", es.EstateID);
cmd.CommandText = sql;
foreach (string name in FieldList)
{
@ -463,35 +472,34 @@ namespace OpenSim.Data.SQLite
public bool LinkRegion(UUID regionID, int estateID)
{
using(SqliteTransaction transaction = m_connection.BeginTransaction())
SqliteTransaction transaction = m_connection.BeginTransaction();
// Delete any existing estate mapping for this region.
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
// Delete any existing estate mapping for this region.
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "delete from estate_map where RegionID = :RegionID";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.CommandText = "delete from estate_map where RegionID = :RegionID";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.ExecuteNonQuery();
cmd.ExecuteNonQuery();
}
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
{
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
if (cmd.ExecuteNonQuery() == 0)
{
transaction.Rollback();
return false;
}
using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand())
else
{
cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
cmd.Transaction = transaction;
cmd.Parameters.AddWithValue(":RegionID", regionID.ToString());
cmd.Parameters.AddWithValue(":EstateID", estateID.ToString());
if (cmd.ExecuteNonQuery() == 0)
{
transaction.Rollback();
return false;
}
else
{
transaction.Commit();
return true;
}
transaction.Commit();
return true;
}
}
}

View File

@ -429,6 +429,75 @@ namespace OpenSim.Data.SQLite
}
}
/// <summary>
/// Load windlight settings from region storage
/// </summary>
/// <param name="regionUUID">RegionID</param>
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
{
RegionLightShareData wl = null;
lock (ds)
{
DataTable windlightTable = ds.Tables["regionwindlight"];
DataRow windlightRow = windlightTable.Rows.Find(regionUUID.ToString());
if (windlightRow == null)
{
wl = new RegionLightShareData();
wl.regionID = regionUUID;
StoreRegionWindlightSettings(wl);
return wl;
}
wl = buildRegionWindlight(windlightRow);
return wl;
}
}
/// <summary>
/// Remove windlight settings from region storage
/// </summary>
/// <param name="regionID">RegionID</param>
public void RemoveRegionWindlightSettings(UUID regionID)
{
lock (ds)
{
DataTable windlightTable = ds.Tables["regionwindlight"];
DataRow windlightRow = windlightTable.Rows.Find(regionID.ToString());
if (windlightRow != null)
{
windlightRow.Delete();
}
}
Commit();
}
/// <summary>
/// Adds an windlight into region storage
/// </summary>
/// <param name="wl">RegionLightShareData</param>
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
lock (ds)
{
DataTable windlightTable = ds.Tables["regionwindlight"];
DataRow windlightRow = windlightTable.Rows.Find(wl.regionID.ToString());
if (windlightRow == null)
{
windlightRow = windlightTable.NewRow();
fillRegionWindlightRow(windlightRow, wl);
windlightTable.Rows.Add(windlightRow);
}
else
{
fillRegionWindlightRow(windlightRow, wl);
}
Commit();
}
}
#region Region Environment Settings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
@ -557,13 +626,10 @@ namespace OpenSim.Data.SQLite
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
addPrim(prim, obj.UUID, regionUUID);
}
primDa.Update(ds, "prims");
shapeDa.Update(ds, "primshapes");
itemsDa.Update(ds, "primitems");
ds.AcceptChanges();
}
// m_log.Info("[Dump of prims]: " + ds.GetXml());
Commit();
// m_log.Info("[Dump of prims]: " + ds.GetXml());
}
/// <summary>
@ -991,9 +1057,12 @@ namespace OpenSim.Data.SQLite
if (rowToCheck["LandUUID"].ToString() == parcel.LandData.GlobalID.ToString())
rowsToDelete.Add(rowToCheck);
}
for (int iter = 0; iter < rowsToDelete.Count; ++iter)
for (int iter = 0; iter < rowsToDelete.Count; iter++)
{
rowsToDelete[iter].Delete();
landaccesslist.Rows.Remove(rowsToDelete[iter]);
}
rowsToDelete.Clear();
foreach (LandAccessEntry entry in parcel.LandData.ParcelAccessList)
{
DataRow newAccessRow = landaccesslist.NewRow();
@ -1243,21 +1312,6 @@ namespace OpenSim.Data.SQLite
createCol(prims, "KeyframeMotion", typeof(Byte[]));
createCol(prims, "PassTouches", typeof(bool));
createCol(prims, "PassCollisions", typeof(bool));
createCol(prims, "Vehicle", typeof(string));
createCol(prims, "RotationAxisLocks", typeof(byte));
createCol(prims, "PhysInertia", typeof(string));
createCol(prims, "standtargetx", typeof(float));
createCol(prims, "standtargety", typeof(float));
createCol(prims, "standtargetz", typeof(float));
createCol(prims, "sitactrange", typeof(float));
createCol(prims, "pseudocrc", typeof(int));
// Add in contraints
prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] };
@ -1300,7 +1354,6 @@ namespace OpenSim.Data.SQLite
createCol(shapes, "ProfileCurve", typeof(Int32));
createCol(shapes, "ProfileHollow", typeof(Int32));
createCol(shapes, "State", typeof(Int32));
createCol(shapes, "LastAttachPoint", typeof(Int32));
// text TODO: this isn't right, but I'm not sure the right
// way to specify this as a blob atm
createCol(shapes, "Texture", typeof(Byte[]));
@ -1402,7 +1455,6 @@ namespace OpenSim.Data.SQLite
createCol(land, "SeeAVs", typeof(Boolean));
createCol(land, "AnyAVSounds", typeof(Boolean));
createCol(land, "GroupAVSounds", typeof(Boolean));
createCol(land, "environment", typeof(string));
land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] };
@ -1467,9 +1519,6 @@ namespace OpenSim.Data.SQLite
createCol(regionsettings, "map_tile_ID", typeof(String));
createCol(regionsettings, "TelehubObject", typeof(String));
createCol(regionsettings, "parcel_tile_ID", typeof(String));
createCol(regionsettings, "block_search", typeof(Boolean));
createCol(regionsettings, "casino", typeof(Boolean));
createCol(regionsettings, "cacheID", typeof(string));
regionsettings.PrimaryKey = new DataColumn[] { regionsettings.Columns["regionUUID"] };
return regionsettings;
}
@ -1675,18 +1724,14 @@ namespace OpenSim.Data.SQLite
Convert.ToSingle(row["SitTargetOffsetY"]),
Convert.ToSingle(row["SitTargetOffsetZ"]));
prim.SitTargetOrientationLL = new Quaternion(
Convert.ToSingle(row["SitTargetOrientX"]),
Convert.ToSingle(row["SitTargetOrientY"]),
Convert.ToSingle(row["SitTargetOrientZ"]),
Convert.ToSingle(row["SitTargetOrientW"]));
prim.StandOffset = new Vector3(
Convert.ToSingle(row["standtargetx"]),
Convert.ToSingle(row["standtargety"]),
Convert.ToSingle(row["standtargetz"])
);
prim.SitActiveRange = Convert.ToSingle(row["sitactrange"]);
Convert.ToSingle(
row["SitTargetOrientX"]),
Convert.ToSingle(
row["SitTargetOrientY"]),
Convert.ToSingle(
row["SitTargetOrientZ"]),
Convert.ToSingle(
row["SitTargetOrientW"]));
prim.ClickAction = Convert.ToByte(row["ClickAction"]);
prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]);
@ -1806,10 +1851,6 @@ namespace OpenSim.Data.SQLite
pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString());
prim.PhysicsInertia = pdata;
int pseudocrc = Convert.ToInt32(row["pseudocrc"]);
if(pseudocrc != 0)
prim.PseudoCRC = pseudocrc;
return prim;
}
@ -1921,36 +1962,6 @@ namespace OpenSim.Data.SQLite
newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
if (row["environment"] is DBNull)
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
else
{
string env = (string)row["environment"];
if (string.IsNullOrEmpty(env))
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
else
{
try
{
ViewerEnvironment VEnv = ViewerEnvironment.FromOSDString(env);
newData.Environment = VEnv;
newData.EnvironmentVersion = VEnv.version;
}
catch
{
newData.Environment = null;
newData.EnvironmentVersion = -1;
}
}
}
return newData;
}
@ -2003,12 +2014,86 @@ namespace OpenSim.Data.SQLite
newSettings.ParcelImageID = new UUID((String)row["parcel_tile_ID"]);
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
newSettings.Casino = Convert.ToBoolean(row["casino"]);
if (!(row["cacheID"] is System.DBNull))
newSettings.CacheID = new UUID((String)row["cacheID"]);
return newSettings;
}
/// <summary>
/// Build a windlight entry from the persisted data.
/// </summary>
/// <param name="row"></param>
/// <returns>RegionLightShareData</returns>
private RegionLightShareData buildRegionWindlight(DataRow row)
{
RegionLightShareData windlight = new RegionLightShareData();
windlight.regionID = new UUID((string)row["region_id"]);
windlight.waterColor.X = Convert.ToSingle(row["water_color_r"]);
windlight.waterColor.Y = Convert.ToSingle(row["water_color_g"]);
windlight.waterColor.Z = Convert.ToSingle(row["water_color_b"]);
//windlight.waterColor.W = Convert.ToSingle(row["water_color_i"]); //not implemented
windlight.waterFogDensityExponent = Convert.ToSingle(row["water_fog_density_exponent"]);
windlight.underwaterFogModifier = Convert.ToSingle(row["underwater_fog_modifier"]);
windlight.reflectionWaveletScale.X = Convert.ToSingle(row["reflection_wavelet_scale_1"]);
windlight.reflectionWaveletScale.Y = Convert.ToSingle(row["reflection_wavelet_scale_2"]);
windlight.reflectionWaveletScale.Z = Convert.ToSingle(row["reflection_wavelet_scale_3"]);
windlight.fresnelScale = Convert.ToSingle(row["fresnel_scale"]);
windlight.fresnelOffset = Convert.ToSingle(row["fresnel_offset"]);
windlight.refractScaleAbove = Convert.ToSingle(row["refract_scale_above"]);
windlight.refractScaleBelow = Convert.ToSingle(row["refract_scale_below"]);
windlight.blurMultiplier = Convert.ToSingle(row["blur_multiplier"]);
windlight.bigWaveDirection.X = Convert.ToSingle(row["big_wave_direction_x"]);
windlight.bigWaveDirection.Y = Convert.ToSingle(row["big_wave_direction_y"]);
windlight.littleWaveDirection.X = Convert.ToSingle(row["little_wave_direction_x"]);
windlight.littleWaveDirection.Y = Convert.ToSingle(row["little_wave_direction_y"]);
windlight.normalMapTexture = new UUID((string)row["normal_map_texture"]);
windlight.horizon.X = Convert.ToSingle(row["horizon_r"]);
windlight.horizon.Y = Convert.ToSingle(row["horizon_g"]);
windlight.horizon.Z = Convert.ToSingle(row["horizon_b"]);
windlight.horizon.W = Convert.ToSingle(row["horizon_i"]);
windlight.hazeHorizon = Convert.ToSingle(row["haze_horizon"]);
windlight.blueDensity.X = Convert.ToSingle(row["blue_density_r"]);
windlight.blueDensity.Y = Convert.ToSingle(row["blue_density_g"]);
windlight.blueDensity.Z = Convert.ToSingle(row["blue_density_b"]);
windlight.blueDensity.W = Convert.ToSingle(row["blue_density_i"]);
windlight.hazeDensity = Convert.ToSingle(row["haze_density"]);
windlight.densityMultiplier = Convert.ToSingle(row["density_multiplier"]);
windlight.distanceMultiplier = Convert.ToSingle(row["distance_multiplier"]);
windlight.maxAltitude = Convert.ToUInt16(row["max_altitude"]);
windlight.sunMoonColor.X = Convert.ToSingle(row["sun_moon_color_r"]);
windlight.sunMoonColor.Y = Convert.ToSingle(row["sun_moon_color_g"]);
windlight.sunMoonColor.Z = Convert.ToSingle(row["sun_moon_color_b"]);
windlight.sunMoonColor.W = Convert.ToSingle(row["sun_moon_color_i"]);
windlight.sunMoonPosition = Convert.ToSingle(row["sun_moon_position"]);
windlight.ambient.X = Convert.ToSingle(row["ambient_r"]);
windlight.ambient.Y = Convert.ToSingle(row["ambient_g"]);
windlight.ambient.Z = Convert.ToSingle(row["ambient_b"]);
windlight.ambient.W = Convert.ToSingle(row["ambient_i"]);
windlight.eastAngle = Convert.ToSingle(row["east_angle"]);
windlight.sunGlowFocus = Convert.ToSingle(row["sun_glow_focus"]);
windlight.sunGlowSize = Convert.ToSingle(row["sun_glow_size"]);
windlight.sceneGamma = Convert.ToSingle(row["scene_gamma"]);
windlight.starBrightness = Convert.ToSingle(row["star_brightness"]);
windlight.cloudColor.X = Convert.ToSingle(row["cloud_color_r"]);
windlight.cloudColor.Y = Convert.ToSingle(row["cloud_color_g"]);
windlight.cloudColor.Z = Convert.ToSingle(row["cloud_color_b"]);
windlight.cloudColor.W = Convert.ToSingle(row["cloud_color_i"]);
windlight.cloudXYDensity.X = Convert.ToSingle(row["cloud_x"]);
windlight.cloudXYDensity.Y = Convert.ToSingle(row["cloud_y"]);
windlight.cloudXYDensity.Z = Convert.ToSingle(row["cloud_density"]);
windlight.cloudCoverage = Convert.ToSingle(row["cloud_coverage"]);
windlight.cloudScale = Convert.ToSingle(row["cloud_scale"]);
windlight.cloudDetailXYDensity.X = Convert.ToSingle(row["cloud_detail_x"]);
windlight.cloudDetailXYDensity.Y = Convert.ToSingle(row["cloud_detail_y"]);
windlight.cloudDetailXYDensity.Z = Convert.ToSingle(row["cloud_detail_density"]);
windlight.cloudScrollX = Convert.ToSingle(row["cloud_scroll_x"]);
windlight.cloudScrollXLock = Convert.ToBoolean(row["cloud_scroll_x_lock"]);
windlight.cloudScrollY = Convert.ToSingle(row["cloud_scroll_y"]);
windlight.cloudScrollYLock = Convert.ToBoolean(row["cloud_scroll_y_lock"]);
windlight.drawClassicClouds = Convert.ToBoolean(row["draw_classic_clouds"]);
return windlight;
}
/// <summary>
/// Build a land access entry from the persisted data.
/// </summary>
@ -2089,14 +2174,6 @@ namespace OpenSim.Data.SQLite
row["SitTargetOrientX"] = sitTargetOrient.X;
row["SitTargetOrientY"] = sitTargetOrient.Y;
row["SitTargetOrientZ"] = sitTargetOrient.Z;
Vector3 standTarget = prim.StandOffset;
row["standtargetx"] = standTarget.X;
row["standtargety"] = standTarget.Y;
row["standtargetz"] = standTarget.Z;
row["sitactrange"] = prim.SitActiveRange;
row["ColorR"] = Convert.ToInt32(prim.Color.R);
row["ColorG"] = Convert.ToInt32(prim.Color.G);
row["ColorB"] = Convert.ToInt32(prim.Color.B);
@ -2122,6 +2199,7 @@ namespace OpenSim.Data.SQLite
row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y;
row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z;
if ((prim.SoundFlags & 1) != 0) // Looped
{
row["LoopedSound"] = prim.Sound.ToString();
@ -2201,7 +2279,6 @@ namespace OpenSim.Data.SQLite
else
row["PhysInertia"] = String.Empty;
row["pseudocrc"] = prim.PseudoCRC;
}
/// <summary>
@ -2289,20 +2366,6 @@ namespace OpenSim.Data.SQLite
row["AnyAVSounds"] = land.AnyAVSounds;
row["GroupAVSounds"] = land.GroupAVSounds;
if (land.Environment == null)
row["environment"] = "";
else
{
try
{
row["environment"] = ViewerEnvironment.ToOSDString(land.Environment);
}
catch
{
row["environment"] = "";
}
}
}
/// <summary>
@ -2363,7 +2426,79 @@ namespace OpenSim.Data.SQLite
row["parcel_tile_ID"] = settings.ParcelImageID.ToString();
row["block_search"] = settings.GodBlockSearch;
row["casino"] = settings.Casino;
row["cacheID"] = settings.CacheID;
}
/// <summary>
///
/// </summary>
/// <param name="row"></param>
/// <param name="windlight"></param>
private static void fillRegionWindlightRow(DataRow row, RegionLightShareData windlight)
{
row["region_id"] = windlight.regionID.ToString();
row["water_color_r"] = windlight.waterColor.X;
row["water_color_g"] = windlight.waterColor.Y;
row["water_color_b"] = windlight.waterColor.Z;
row["water_color_i"] = 1; //windlight.waterColor.W; //not implemented
row["water_fog_density_exponent"] = windlight.waterFogDensityExponent;
row["underwater_fog_modifier"] = windlight.underwaterFogModifier;
row["reflection_wavelet_scale_1"] = windlight.reflectionWaveletScale.X;
row["reflection_wavelet_scale_2"] = windlight.reflectionWaveletScale.Y;
row["reflection_wavelet_scale_3"] = windlight.reflectionWaveletScale.Z;
row["fresnel_scale"] = windlight.fresnelScale;
row["fresnel_offset"] = windlight.fresnelOffset;
row["refract_scale_above"] = windlight.refractScaleAbove;
row["refract_scale_below"] = windlight.refractScaleBelow;
row["blur_multiplier"] = windlight.blurMultiplier;
row["big_wave_direction_x"] = windlight.bigWaveDirection.X;
row["big_wave_direction_y"] = windlight.bigWaveDirection.Y;
row["little_wave_direction_x"] = windlight.littleWaveDirection.X;
row["little_wave_direction_y"] = windlight.littleWaveDirection.Y;
row["normal_map_texture"] = windlight.normalMapTexture.ToString();
row["horizon_r"] = windlight.horizon.X;
row["horizon_g"] = windlight.horizon.Y;
row["horizon_b"] = windlight.horizon.Z;
row["horizon_i"] = windlight.horizon.W;
row["haze_horizon"] = windlight.hazeHorizon;
row["blue_density_r"] = windlight.blueDensity.X;
row["blue_density_g"] = windlight.blueDensity.Y;
row["blue_density_b"] = windlight.blueDensity.Z;
row["blue_density_i"] = windlight.blueDensity.W;
row["haze_density"] = windlight.hazeDensity;
row["density_multiplier"] = windlight.densityMultiplier;
row["distance_multiplier"] = windlight.distanceMultiplier;
row["max_altitude"] = windlight.maxAltitude;
row["sun_moon_color_r"] = windlight.sunMoonColor.X;
row["sun_moon_color_g"] = windlight.sunMoonColor.Y;
row["sun_moon_color_b"] = windlight.sunMoonColor.Z;
row["sun_moon_color_i"] = windlight.sunMoonColor.W;
row["sun_moon_position"] = windlight.sunMoonPosition;
row["ambient_r"] = windlight.ambient.X;
row["ambient_g"] = windlight.ambient.Y;
row["ambient_b"] = windlight.ambient.Z;
row["ambient_i"] = windlight.ambient.W;
row["east_angle"] = windlight.eastAngle;
row["sun_glow_focus"] = windlight.sunGlowFocus;
row["sun_glow_size"] = windlight.sunGlowSize;
row["scene_gamma"] = windlight.sceneGamma;
row["star_brightness"] = windlight.starBrightness;
row["cloud_color_r"] = windlight.cloudColor.X;
row["cloud_color_g"] = windlight.cloudColor.Y;
row["cloud_color_b"] = windlight.cloudColor.Z;
row["cloud_color_i"] = windlight.cloudColor.W;
row["cloud_x"] = windlight.cloudXYDensity.X;
row["cloud_y"] = windlight.cloudXYDensity.Y;
row["cloud_density"] = windlight.cloudXYDensity.Z;
row["cloud_coverage"] = windlight.cloudCoverage;
row["cloud_scale"] = windlight.cloudScale;
row["cloud_detail_x"] = windlight.cloudDetailXYDensity.X;
row["cloud_detail_y"] = windlight.cloudDetailXYDensity.Y;
row["cloud_detail_density"] = windlight.cloudDetailXYDensity.Z;
row["cloud_scroll_x"] = windlight.cloudScrollX;
row["cloud_scroll_x_lock"] = windlight.cloudScrollXLock;
row["cloud_scroll_y"] = windlight.cloudScrollY;
row["cloud_scroll_y_lock"] = windlight.cloudScrollYLock;
row["draw_classic_clouds"] = windlight.drawClassicClouds;
}
/// <summary>

View File

@ -495,6 +495,10 @@ namespace OpenSim.Data.Tests
Assert.AreEqual(pricePerMeter, estateSettings.PricePerMeter);
Assert.AreEqual(redirectGridX, estateSettings.RedirectGridX);
Assert.AreEqual(redirectGridY, estateSettings.RedirectGridY);
Assert.AreEqual(useGlobalTime, estateSettings.UseGlobalTime);
Assert.AreEqual(fixedSun, estateSettings.FixedSun);
DataTestUtil.AssertDoubleEqualsWithTolerance(sunPosition, estateSettings.SunPosition);
Assert.AreEqual(allowVoice, estateSettings.AllowVoice);
Assert.AreEqual(allowDirectTeleport, estateSettings.AllowDirectTeleport);

View File

@ -269,12 +269,12 @@ namespace OpenSim.Data.Tests
random.NextBytes(partsys);
DateTime expires = new DateTime(2008, 12, 20);
DateTime rezzed = new DateTime(2009, 07, 15);
Vector3 groupos = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 offset = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Quaternion rotoff = new Quaternion(random.Next(1),random.Next(1),random.Next(1),random.Next(1));
Vector3 velocity = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 angvelo = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 accel = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 groupos = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 offset = new Vector3(random.Next(),random.Next(),random.Next());
Quaternion rotoff = new Quaternion(random.Next(),random.Next(),random.Next(),random.Next());
Vector3 velocity = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 angvelo = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 accel = new Vector3(random.Next(),random.Next(),random.Next());
string description = name;
Color color = Color.FromArgb(255, 165, 50, 100);
string text = "All Your Base Are Belong to Us";
@ -289,7 +289,7 @@ namespace OpenSim.Data.Tests
pbshap.ProfileBegin = ushort.MaxValue;
pbshap.ProfileEnd = ushort.MaxValue;
pbshap.ProfileHollow = ushort.MaxValue;
Vector3 scale = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next());
RegionInfo regionInfo = new RegionInfo();
regionInfo.RegionID = region3;
@ -378,9 +378,9 @@ namespace OpenSim.Data.Tests
SceneObjectPart p = sogs[0].RootPart;
Assert.That(regionh,Is.EqualTo(p.RegionHandle), "Assert.That(regionh,Is.EqualTo(p.RegionHandle))");
//Assert.That(localid,Is.EqualTo(p.LocalId), "Assert.That(localid,Is.EqualTo(p.LocalId))");
Assert.That(groupos, Is.EqualTo(p.GroupPosition), "Assert.That(groupos,Is.EqualTo(p.GroupPosition))");
Assert.That(groupos,Is.EqualTo(p.GroupPosition), "Assert.That(groupos,Is.EqualTo(p.GroupPosition))");
Assert.That(name,Is.EqualTo(p.Name), "Assert.That(name,Is.EqualTo(p.Name))");
Assert.That(rotoff, Is.EqualTo(p.RotationOffset), "Assert.That(rotoff,Is.EqualTo(p.RotationOffset))");
Assert.That(rotoff,Is.EqualTo(p.RotationOffset), "Assert.That(rotoff,Is.EqualTo(p.RotationOffset))");
Assert.That(uuid,Is.EqualTo(p.UUID), "Assert.That(uuid,Is.EqualTo(p.UUID))");
Assert.That(creator,Is.EqualTo(p.CreatorID), "Assert.That(creator,Is.EqualTo(p.CreatorID))");
//Assert.That(iserial,Is.EqualTo(p.InventorySerial), "Assert.That(iserial,Is.EqualTo(p.InventorySerial))");
@ -443,12 +443,12 @@ namespace OpenSim.Data.Tests
random.NextBytes(partsys);
DateTime expires = new DateTime(2010, 12, 20);
DateTime rezzed = new DateTime(2005, 07, 15);
Vector3 groupos = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 offset = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Quaternion rotoff = new Quaternion(random.Next(100000),random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 velocity = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 angvelo = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 accel = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 groupos = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 offset = new Vector3(random.Next(),random.Next(),random.Next());
Quaternion rotoff = new Quaternion(random.Next(),random.Next(),random.Next(),random.Next());
Vector3 velocity = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 angvelo = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 accel = new Vector3(random.Next(),random.Next(),random.Next());
string description = name;
Color color = Color.FromArgb(255, 255, 255, 0);
string text = "What You Say?{]\vz~";
@ -536,12 +536,12 @@ namespace OpenSim.Data.Tests
{
UUID tmp = UUID.Random();
SceneObjectPart sop = NewSOP(("Test SOP " + i.ToString()),tmp);
Vector3 groupos = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 offset = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Quaternion rotoff = new Quaternion(random.Next(100000),random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 velocity = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 angvelo = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 accel = new Vector3(random.Next(100000),random.Next(100000),random.Next(100000));
Vector3 groupos = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 offset = new Vector3(random.Next(),random.Next(),random.Next());
Quaternion rotoff = new Quaternion(random.Next(),random.Next(),random.Next(),random.Next());
Vector3 velocity = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 angvelo = new Vector3(random.Next(),random.Next(),random.Next());
Vector3 accel = new Vector3(random.Next(),random.Next(),random.Next());
sop.GroupPosition = groupos;
sop.RotationOffset = rotoff;
@ -869,6 +869,7 @@ namespace OpenSim.Data.Tests
double terrainlower = random.Next();
Vector3 sunvector = new Vector3((float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5),(float)Math.Round(random.NextDouble(),5));
UUID terimgid = UUID.Random();
double sunpos = random.Next();
UUID cov = UUID.Random();
RegionSettings r1 = db.LoadRegionSettings(region1);
@ -902,8 +903,10 @@ namespace OpenSim.Data.Tests
r1.TerrainLowerLimit = terrainlower;
r1.UseEstateSun = false;
r1.Sandbox = true;
r1.SunVector = sunvector;
r1.TerrainImageID = terimgid;
r1.FixedSun = true;
r1.SunPosition = sunpos;
r1.Covenant = cov;
db.StoreRegionSettings(r1);
@ -938,8 +941,12 @@ namespace OpenSim.Data.Tests
Assert.That(r1a.WaterHeight,Is.EqualTo(waterh), "Assert.That(r1a.WaterHeight,Is.EqualTo(waterh))");
Assert.That(r1a.TerrainRaiseLimit,Is.EqualTo(terrainraise), "Assert.That(r1a.TerrainRaiseLimit,Is.EqualTo(terrainraise))");
Assert.That(r1a.TerrainLowerLimit,Is.EqualTo(terrainlower), "Assert.That(r1a.TerrainLowerLimit,Is.EqualTo(terrainlower))");
Assert.That(r1a.UseEstateSun,Is.False);
Assert.That(r1a.Sandbox,Is.True);
Assert.That(r1a.SunVector,Is.EqualTo(sunvector), "Assert.That(r1a.SunVector,Is.EqualTo(sunvector))");
//Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid), "Assert.That(r1a.TerrainImageID,Is.EqualTo(terimgid))");
Assert.That(r1a.FixedSun,Is.True);
Assert.That(r1a.SunPosition, Is.EqualTo(sunpos), "Assert.That(r1a.SunPosition, Is.EqualTo(sunpos))");
Assert.That(r1a.Covenant, Is.EqualTo(cov), "Assert.That(r1a.Covenant, Is.EqualTo(cov))");
}
@ -963,7 +970,7 @@ namespace OpenSim.Data.Tests
db.StoreTerrain(t1, region1);
// store terrain is async
Thread.Sleep(500);
Thread.Sleep(1000);
Assert.That(db.LoadTerrain(zero), Is.Null);
Assert.That(db.LoadTerrain(region1), Is.Not.Null);
@ -993,7 +1000,7 @@ namespace OpenSim.Data.Tests
db.StoreTerrain(baseterrain2, region1);
// store terrain is async
Thread.Sleep(500);
Thread.Sleep(1000);
double[,] t1 = db.LoadTerrain(region1);
Assert.That(CompareTerrain(t1, baseterrain1), Is.False);

View File

@ -26,7 +26,6 @@
*/
using System.Collections.Generic;
using System.Collections.Concurrent;
using OpenMetaverse;
namespace OpenSim.Framework
@ -42,18 +41,26 @@ namespace OpenSim.Framework
/// <remarks>
/// We lock this for operations both on this dictionary and on m_agentCircuitsByUUID
/// </remarks>
private ConcurrentDictionary<uint, AgentCircuitData> m_agentCircuits = new ConcurrentDictionary<uint, AgentCircuitData>();
private Dictionary<uint, AgentCircuitData> m_agentCircuits = new Dictionary<uint, AgentCircuitData>();
/// <summary>
/// Agent circuits indexed by agent UUID.
/// </summary>
private ConcurrentDictionary<UUID, AgentCircuitData> m_agentCircuitsByUUID = new ConcurrentDictionary<UUID, AgentCircuitData>();
private Dictionary<UUID, AgentCircuitData> m_agentCircuitsByUUID = new Dictionary<UUID, AgentCircuitData>();
public virtual AuthenticateResponse AuthenticateSession(UUID sessionID, UUID agentID, uint circuitcode)
{
AgentCircuitData validcircuit = null;
lock (m_agentCircuits)
{
if (m_agentCircuits.ContainsKey(circuitcode))
validcircuit = m_agentCircuits[circuitcode];
}
AuthenticateResponse user = new AuthenticateResponse();
if (!m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData validcircuit) || validcircuit == null)
if (validcircuit == null)
{
//don't have this circuit code in our list
user.Authorised = false;
@ -79,6 +86,7 @@ namespace OpenSim.Framework
// Invalid
user.Authorised = false;
}
return user;
}
@ -89,39 +97,65 @@ namespace OpenSim.Framework
/// <param name="agentData"></param>
public virtual void AddNewCircuit(uint circuitCode, AgentCircuitData agentData)
{
RemoveCircuit(agentData.AgentID); // no duplications
m_agentCircuits[circuitCode] = agentData;
m_agentCircuitsByUUID[agentData.AgentID] = agentData;
lock (m_agentCircuits)
{
if (m_agentCircuits.ContainsKey(circuitCode))
{
m_agentCircuits[circuitCode] = agentData;
m_agentCircuitsByUUID[agentData.AgentID] = agentData;
}
else
{
m_agentCircuits.Add(circuitCode, agentData);
m_agentCircuitsByUUID[agentData.AgentID] = agentData;
}
}
}
public virtual void RemoveCircuit(uint circuitCode)
{
if (m_agentCircuits.TryRemove(circuitCode, out AgentCircuitData ac))
lock (m_agentCircuits)
{
m_agentCircuitsByUUID.TryRemove(ac.AgentID, out AgentCircuitData dummy);
if (m_agentCircuits.ContainsKey(circuitCode))
{
UUID agentID = m_agentCircuits[circuitCode].AgentID;
m_agentCircuits.Remove(circuitCode);
m_agentCircuitsByUUID.Remove(agentID);
}
}
}
public virtual void RemoveCircuit(UUID agentID)
{
if (m_agentCircuitsByUUID.TryRemove(agentID, out AgentCircuitData ac))
lock (m_agentCircuits)
{
m_agentCircuits.TryRemove(ac.circuitcode, out AgentCircuitData dummy);
if (m_agentCircuitsByUUID.ContainsKey(agentID))
{
uint circuitCode = m_agentCircuitsByUUID[agentID].circuitcode;
m_agentCircuits.Remove(circuitCode);
m_agentCircuitsByUUID.Remove(agentID);
}
}
}
public AgentCircuitData GetAgentCircuitData(uint circuitCode)
{
if(m_agentCircuits.TryGetValue(circuitCode, out AgentCircuitData agentCircuit))
return agentCircuit;
return null;
AgentCircuitData agentCircuit = null;
lock (m_agentCircuits)
m_agentCircuits.TryGetValue(circuitCode, out agentCircuit);
return agentCircuit;
}
public AgentCircuitData GetAgentCircuitData(UUID agentID)
{
if(m_agentCircuitsByUUID.TryGetValue(agentID, out AgentCircuitData agentCircuit))
return agentCircuit;
return null;
AgentCircuitData agentCircuit = null;
lock (m_agentCircuits)
m_agentCircuitsByUUID.TryGetValue(agentID, out agentCircuit);
return agentCircuit;
}
/// <summary>
@ -136,16 +170,21 @@ namespace OpenSim.Framework
public void UpdateAgentData(AgentCircuitData agentData)
{
if (m_agentCircuits.TryGetValue(agentData.circuitcode, out AgentCircuitData ac))
lock (m_agentCircuits)
{
ac.firstname = agentData.firstname;
ac.lastname = agentData.lastname;
ac.startpos = agentData.startpos;
ac.startfar = agentData.startfar;
if (m_agentCircuits.ContainsKey((uint) agentData.circuitcode))
{
m_agentCircuits[(uint) agentData.circuitcode].firstname = agentData.firstname;
m_agentCircuits[(uint) agentData.circuitcode].lastname = agentData.lastname;
m_agentCircuits[(uint)agentData.circuitcode].startpos = agentData.startpos;
m_agentCircuits[(uint)agentData.circuitcode].startfar = agentData.startfar;
// Updated for when we don't know them before calling Scene.NewUserConnection
ac.SecureSessionID = agentData.SecureSessionID;
ac.SessionID = agentData.SessionID;
// Updated for when we don't know them before calling Scene.NewUserConnection
m_agentCircuits[(uint) agentData.circuitcode].SecureSessionID = agentData.SecureSessionID;
m_agentCircuits[(uint) agentData.circuitcode].SessionID = agentData.SessionID;
// m_log.Debug("update user start pos is " + agentData.startpos.X + " , " + agentData.startpos.Y + " , " + agentData.startpos.Z);
}
}
}
@ -154,30 +193,38 @@ namespace OpenSim.Framework
/// </summary>
/// <param name="circuitcode"></param>
/// <param name="newcircuitcode"></param>
public bool TryChangeCircuitCode(uint circuitcode, uint newcircuitcode)
public bool TryChangeCiruitCode(uint circuitcode, uint newcircuitcode)
{
if(m_agentCircuits.ContainsKey(newcircuitcode))
return false;
if (m_agentCircuits.TryRemove(circuitcode, out AgentCircuitData agentData))
lock (m_agentCircuits)
{
agentData.circuitcode = newcircuitcode;
m_agentCircuits.TryAdd(newcircuitcode, agentData);
m_agentCircuitsByUUID[agentData.AgentID] = agentData;
return true;
if (m_agentCircuits.ContainsKey((uint)circuitcode) && !m_agentCircuits.ContainsKey((uint)newcircuitcode))
{
AgentCircuitData agentData = m_agentCircuits[(uint)circuitcode];
agentData.circuitcode = newcircuitcode;
m_agentCircuits.Remove((uint)circuitcode);
m_agentCircuits.Add(newcircuitcode, agentData);
return true;
}
}
return false;
}
public void UpdateAgentChildStatus(uint circuitcode, bool childstatus)
{
if (m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData ac))
ac.child = childstatus;
lock (m_agentCircuits)
if (m_agentCircuits.ContainsKey(circuitcode))
m_agentCircuits[circuitcode].child = childstatus;
}
public bool GetAgentChildStatus(uint circuitcode)
{
if (m_agentCircuits.TryGetValue(circuitcode, out AgentCircuitData ac))
return ac.child;
lock (m_agentCircuits)
if (m_agentCircuits.ContainsKey(circuitcode))
return m_agentCircuits[circuitcode].child;
return false;
}
}

View File

@ -112,13 +112,12 @@ namespace OpenSim.Framework
/// <param name="args"></param>
public void UnpackUpdateMessage(OSDMap args)
{
OSD tmp;
if (args.TryGetValue("animation", out tmp))
animID = tmp.AsUUID();
if (args.TryGetValue("object_id", out tmp))
objectID = tmp.AsUUID();
if (args.TryGetValue("seq_num", out tmp))
sequenceNum = tmp.AsInteger();
if (args["animation"] != null)
animID = args["animation"].AsUUID();
if (args["object_id"] != null)
objectID = args["object_id"].AsUUID();
if (args["seq_num"] != null)
sequenceNum = args["seq_num"].AsInteger();
}
public override bool Equals(object obj)

View File

@ -34,13 +34,12 @@ using OpenMetaverse;
namespace OpenSim.Framework
{
[Flags]
// this enum is stuck, can not be changed or will break compatibilty with any version older than that change
public enum AssetFlags : int
{
Normal = 0, // Immutable asset
Maptile = 1, // What it says
Rewritable = 2, // Content can be rewritten
Collectable = 4, // Can be GC'ed after some time
Collectable = 4 // Can be GC'ed after some time
}
/// <summary>

View File

@ -817,7 +817,7 @@ namespace OpenSim.Framework
return data;
}
public OSDMap PackForNotecard(bool NoHuds = true)
public OSDMap PackForNotecard()
{
OSDMap data = new OSDMap();
@ -868,13 +868,7 @@ namespace OpenSim.Framework
// Attachments
OSDArray attachs = new OSDArray(m_attachments.Count);
foreach (AvatarAttachment attach in GetAttachments())
{
if (NoHuds &&
attach.AttachPoint >= (uint)AttachmentPoint.HUDCenter2 &&
attach.AttachPoint <= (uint)AttachmentPoint.HUDBottomRight)
continue;
attachs.Add(attach.Pack());
}
data["attachments"] = attachs;
}

View File

@ -571,141 +571,145 @@ namespace OpenSim.Framework
public virtual void Unpack(OSDMap args, IScene scene, EntityTransferContext ctx)
{
//m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data");
OSD tmp;
if (args.TryGetValue("region_id", out tmp) && tmp != null)
UUID.TryParse(tmp.AsString(), out RegionID);
if (args.TryGetValue("circuit_code", out tmp) && tmp != null)
UInt32.TryParse(tmp.AsString(), out CircuitCode);
if (args.ContainsKey("region_id"))
UUID.TryParse(args["region_id"].AsString(), out RegionID);
if (args.TryGetValue("agent_uuid", out tmp) && tmp != null)
AgentID = tmp.AsUUID();
if (args["circuit_code"] != null)
UInt32.TryParse((string)args["circuit_code"].AsString(), out CircuitCode);
if (args.TryGetValue("session_uuid", out tmp) && tmp != null)
SessionID = tmp.AsUUID();
if (args["agent_uuid"] != null)
AgentID = args["agent_uuid"].AsUUID();
if (args.TryGetValue("position", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out Position);
if (args["session_uuid"] != null)
SessionID = args["session_uuid"].AsUUID();
if (args.TryGetValue("velocity", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out Velocity);
if (args["position"] != null)
Vector3.TryParse(args["position"].AsString(), out Position);
if (args.TryGetValue("center", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out Center);
if (args["velocity"] != null)
Vector3.TryParse(args["velocity"].AsString(), out Velocity);
if (args.TryGetValue("size", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out Size);
if (args["center"] != null)
Vector3.TryParse(args["center"].AsString(), out Center);
if (args.TryGetValue("at_axis", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out AtAxis);
if (args["size"] != null)
Vector3.TryParse(args["size"].AsString(), out Size);
if (args.TryGetValue("left_axis", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out AtAxis);
if (args["at_axis"] != null)
Vector3.TryParse(args["at_axis"].AsString(), out AtAxis);
if (args.TryGetValue("up_axis", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out AtAxis);
if (args["left_axis"] != null)
Vector3.TryParse(args["left_axis"].AsString(), out AtAxis);
if (args.TryGetValue("wait_for_root", out tmp) && tmp != null)
SenderWantsToWaitForRoot = tmp.AsBoolean();
if (args["up_axis"] != null)
Vector3.TryParse(args["up_axis"].AsString(), out AtAxis);
if (args.TryGetValue("far", out tmp) && tmp != null)
Far = (float)(tmp.AsReal());
if (args.ContainsKey("wait_for_root") && args["wait_for_root"] != null)
SenderWantsToWaitForRoot = args["wait_for_root"].AsBoolean();
if (args.TryGetValue("aspect", out tmp) && tmp != null)
Aspect = (float)tmp.AsReal();
if (args["far"] != null)
Far = (float)(args["far"].AsReal());
if (args.TryGetValue("throttles", out tmp) && tmp != null)
Throttles = tmp.AsBinary();
if (args["aspect"] != null)
Aspect = (float)args["aspect"].AsReal();
if (args.TryGetValue("locomotion_state", out tmp) && tmp != null)
UInt32.TryParse(tmp.AsString(), out LocomotionState);
if (args["throttles"] != null)
Throttles = args["throttles"].AsBinary();
if (args.TryGetValue("head_rotation", out tmp) && tmp != null)
Quaternion.TryParse(tmp.AsString(), out HeadRotation);
if (args["locomotion_state"] != null)
UInt32.TryParse(args["locomotion_state"].AsString(), out LocomotionState);
if (args.TryGetValue("body_rotation", out tmp) && tmp != null)
Quaternion.TryParse(tmp.AsString(), out BodyRotation);
if (args["head_rotation"] != null)
Quaternion.TryParse(args["head_rotation"].AsString(), out HeadRotation);
if (args.TryGetValue("control_flags", out tmp) && tmp != null)
UInt32.TryParse(tmp.AsString(), out ControlFlags);
if (args["body_rotation"] != null)
Quaternion.TryParse(args["body_rotation"].AsString(), out BodyRotation);
if (args.TryGetValue("energy_level", out tmp) && tmp != null)
EnergyLevel = (float)(tmp.AsReal());
if (args["control_flags"] != null)
UInt32.TryParse(args["control_flags"].AsString(), out ControlFlags);
if (args.TryGetValue("god_data", out tmp) && tmp != null)
GodData = tmp;
if (args["energy_level"] != null)
EnergyLevel = (float)(args["energy_level"].AsReal());
if (args.TryGetValue("always_run", out tmp) && tmp != null)
AlwaysRun = tmp.AsBoolean();
//if (args["god_level"] != null)
// Byte.TryParse(args["god_level"].AsString(), out GodLevel);
if (args.TryGetValue("prey_agent", out tmp) && tmp != null)
PreyAgent = tmp.AsUUID();
if (args.ContainsKey("god_data") && args["god_data"] != null)
GodData = args["god_data"];
if (args.TryGetValue("agent_access", out tmp) && tmp != null)
Byte.TryParse(tmp.AsString(), out AgentAccess);
if (args["always_run"] != null)
AlwaysRun = args["always_run"].AsBoolean();
if (args.TryGetValue("agent_cof", out tmp) && tmp != null)
agentCOF = tmp.AsUUID();
if (args["prey_agent"] != null)
PreyAgent = args["prey_agent"].AsUUID();
if (args.TryGetValue("crossingflags", out tmp) && tmp != null)
CrossingFlags = (byte)tmp.AsInteger();
if (args["agent_access"] != null)
Byte.TryParse(args["agent_access"].AsString(), out AgentAccess);
if (args.ContainsKey("agent_cof") && args["agent_cof"] != null)
agentCOF = args["agent_cof"].AsUUID();
if (args.ContainsKey("crossingflags") && args["crossingflags"] != null)
CrossingFlags = (byte)args["crossingflags"].AsInteger();
if(CrossingFlags != 0)
{
if (args.TryGetValue("crossExtraFlags", out tmp) && tmp != null)
CrossExtraFlags = (byte)tmp.AsInteger();
if (args.ContainsKey("crossExtraFlags") && args["crossExtraFlags"] != null)
CrossExtraFlags = (byte)args["crossExtraFlags"].AsInteger();
}
if (args.TryGetValue("active_group_id", out tmp) && tmp != null)
ActiveGroupID = tmp.AsUUID();
if (args.ContainsKey("active_group_id") && args["active_group_id"] != null)
ActiveGroupID = args["active_group_id"].AsUUID();
if (args.TryGetValue("active_group_name", out tmp) && tmp != null)
ActiveGroupName = tmp.AsString();
if (args.ContainsKey("active_group_name") && args["active_group_name"] != null)
ActiveGroupName = args["active_group_name"].AsString();
if(args.TryGetValue("active_group_title", out tmp) && tmp != null)
ActiveGroupTitle = tmp.AsString();
if(args.ContainsKey("active_group_title") && args["active_group_title"] != null)
ActiveGroupTitle = args["active_group_title"].AsString();
if (args.TryGetValue("children_seeds", out tmp) && tmp is OSDArray)
if (args.ContainsKey("children_seeds") && (args["children_seeds"] != null) &&
(args["children_seeds"].Type == OSDType.Array))
{
OSDArray childrenSeeds = (OSDArray)tmp;
OSDArray childrenSeeds = (OSDArray)(args["children_seeds"]);
ChildrenCapSeeds = new Dictionary<ulong, string>();
foreach (OSD o in childrenSeeds)
{
if (o is OSDMap)
if (o.Type == OSDType.Map)
{
ulong handle = 0;
string seed = "";
OSDMap pair = (OSDMap)o;
if (pair.TryGetValue("handle", out tmp))
if (!UInt64.TryParse(tmp.AsString(), out handle))
if (pair["handle"] != null)
if (!UInt64.TryParse(pair["handle"].AsString(), out handle))
continue;
if (pair.TryGetValue("seed", out tmp))
seed = tmp.AsString();
if (pair["seed"] != null)
seed = pair["seed"].AsString();
if (!ChildrenCapSeeds.ContainsKey(handle))
ChildrenCapSeeds.Add(handle, seed);
}
}
}
if (args.TryGetValue("animations", out tmp) && tmp is OSDArray)
if ((args["animations"] != null) && (args["animations"]).Type == OSDType.Array)
{
OSDArray anims = (OSDArray)tmp;
OSDArray anims = (OSDArray)(args["animations"]);
Anims = new Animation[anims.Count];
int i = 0;
foreach (OSD o in anims)
{
if (o is OSDMap)
if (o.Type == OSDType.Map)
{
Anims[i++] = new Animation((OSDMap)o);
}
}
}
if (args.TryGetValue("default_animation", out tmp) && tmp is OSDMap)
if (args["default_animation"] != null)
{
try
{
DefaultAnim = new Animation((OSDMap)tmp);
DefaultAnim = new Animation((OSDMap)args["default_animation"]);
}
catch
{
@ -713,11 +717,11 @@ namespace OpenSim.Framework
}
}
if (args.TryGetValue("animation_state", out tmp) && tmp is OSDMap)
if (args["animation_state"] != null)
{
try
{
AnimState = new Animation((OSDMap)tmp);
AnimState = new Animation((OSDMap)args["animation_state"]);
}
catch
{
@ -727,9 +731,9 @@ namespace OpenSim.Framework
MovementAnimationOverRides.Clear();
if (args.TryGetValue("movementAO", out tmp) && tmp is OSDArray)
if (args["movementAO"] != null && args["movementAO"].Type == OSDType.Array)
{
OSDArray AOs = (OSDArray)tmp;
OSDArray AOs = (OSDArray)(args["movementAO"]);
int count = AOs.Count;
for (int i = 0; i < count; i++)
@ -744,8 +748,8 @@ namespace OpenSim.Framework
}
}
if (args.TryGetValue("motion_state", out tmp) && tmp != null)
MotionState = (byte)tmp.AsInteger();
if (args.ContainsKey("motion_state"))
MotionState = (byte)args["motion_state"].AsInteger();
//if ((args["agent_textures"] != null) && (args["agent_textures"]).Type == OSDType.Array)
//{
@ -758,10 +762,10 @@ namespace OpenSim.Framework
// packed_appearence should contain all appearance information
if (args.TryGetValue("packed_appearance", out tmp) && tmp is OSDMap)
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
{
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance");
Appearance = new AvatarAppearance((OSDMap)tmp);
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
}
else
{
@ -773,19 +777,19 @@ namespace OpenSim.Framework
// The code to unpack textures, visuals, wearables and attachments
// should be removed; packed appearance contains the full appearance
// This is retained for backward compatibility only
if (args.TryGetValue("texture_entry", out tmp) && tmp != null)
if (args["texture_entry"] != null)
{
byte[] rawtextures = tmp.AsBinary();
byte[] rawtextures = args["texture_entry"].AsBinary();
Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length);
Appearance.SetTextureEntries(textures);
}
if (args.TryGetValue("visual_params", out tmp) && tmp != null)
Appearance.SetVisualParams(tmp.AsBinary());
if (args["visual_params"] != null)
Appearance.SetVisualParams(args["visual_params"].AsBinary());
if (args.TryGetValue("wearables", out tmp) && tmp is OSDArray)
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
{
OSDArray wears = (OSDArray)tmp;
OSDArray wears = (OSDArray)(args["wearables"]);
for (int i = 0; i < wears.Count / 2; i++)
{
@ -794,12 +798,12 @@ namespace OpenSim.Framework
}
}
if (args.TryGetValue("attachments", out tmp) && tmp is OSDArray)
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
{
OSDArray attachs = (OSDArray)tmp;
OSDArray attachs = (OSDArray)(args["attachments"]);
foreach (OSD o in attachs)
{
if (o is OSDMap)
if (o.Type == OSDType.Map)
{
// We know all of these must end up as attachments so we
// append rather than replace to ensure multiple attachments
@ -812,35 +816,35 @@ namespace OpenSim.Framework
// end of code to remove
}
if (args.TryGetValue("controllers", out tmp) && tmp is OSDArray)
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
{
OSDArray controls = (OSDArray)tmp;
OSDArray controls = (OSDArray)(args["controllers"]);
Controllers = new ControllerData[controls.Count];
int i = 0;
foreach (OSD o in controls)
{
if (o is OSDMap)
if (o.Type == OSDType.Map)
{
Controllers[i++] = new ControllerData((OSDMap)o);
}
}
}
if (args.TryGetValue("callback_uri", out tmp) && tmp != null)
CallbackURI = tmp.AsString();
if (args["callback_uri"] != null)
CallbackURI = args["callback_uri"].AsString();
if (args.TryGetValue("cb_uri", out tmp) && tmp != null)
NewCallbackURI = tmp.AsString();
if (args["cb_uri"] != null)
NewCallbackURI = args["cb_uri"].AsString();
// Attachment objects
if (args.TryGetValue("attach_objects", out tmp) && tmp is OSDArray)
if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array)
{
OSDArray attObjs = (OSDArray)tmp;
OSDArray attObjs = (OSDArray)(args["attach_objects"]);
AttachmentObjects = new List<ISceneObject>();
AttachmentObjectStates = new List<string>();
foreach (OSD o in attObjs)
{
if (o is OSDMap)
if (o.Type == OSDType.Map)
{
OSDMap info = (OSDMap)o;
ISceneObject so = scene.DeserializeObject(info["sog"].AsString());
@ -852,10 +856,10 @@ namespace OpenSim.Framework
}
}
if (args.TryGetValue("parent_part", out tmp) && tmp != null)
ParentPart = tmp.AsUUID();
if (args.TryGetValue("sit_offset", out tmp) && tmp != null)
Vector3.TryParse(tmp.AsString(), out SitOffset);
if (args["parent_part"] != null)
ParentPart = args["parent_part"].AsUUID();
if (args["sit_offset"] != null)
Vector3.TryParse(args["sit_offset"].AsString(), out SitOffset);
}
public AgentData()

View File

@ -84,7 +84,7 @@ namespace OpenSim.Framework.Console
{
}
public virtual void Output(string format)
public void Output(string format)
{
System.Console.WriteLine(format);
}

View File

@ -389,11 +389,6 @@ namespace OpenSim.Framework.Console
System.Console.WriteLine();
}
public override void Output(string format)
{
Output(format, null);
}
public override void Output(string format, params object[] components)
{
string level = null;

View File

@ -190,11 +190,6 @@ namespace OpenSim.Framework.Console
m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand);
}
public override void Output(string format)
{
Output(format, null);
}
public override void Output(string format, params object[] components)
{
string level = null;
@ -429,9 +424,10 @@ namespace OpenSim.Framework.Console
}
// This call is a CAP. The URL is the authentication.
string uri = "/ReadResponses/" + sessionID.ToString();
string uri = "/ReadResponses/" + sessionID.ToString() + "/";
m_Server.AddPollServiceHTTPHandler(new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, null, sessionID,25000)); // 25 secs timeout
m_Server.AddPollServiceHTTPHandler(
uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, null, sessionID,25000)); // 25 secs timeout
// Our reply is an XML document.
// TODO: Change this to Linq.Xml

View File

@ -25,7 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenMetaverse;
namespace OpenSim.Framework
{
@ -48,9 +47,6 @@ namespace OpenSim.Framework
public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";
public static readonly UUID m_MrOpenSimID = new UUID("11111111-1111-0000-0000-000100bba000");
public static readonly DateTime m_MrOpenSimBorn = new DateTime(2007, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public enum EstateAccessCodex : uint
{
AllowedAccess = 1,

View File

@ -115,28 +115,25 @@ namespace OpenSim.Framework
// Used by the sim
//
private bool m_UseGlobalTime = false;
private bool m_UseGlobalTime = true;
public bool UseGlobalTime
{
get { return m_UseGlobalTime; }
//set { m_UseGlobalTime = value; }
set { m_UseGlobalTime = false; }
set { m_UseGlobalTime = value; }
}
private bool m_FixedSun = false;
public bool FixedSun
{
get { return m_FixedSun; }
// set { m_FixedSun = value; }
set { m_FixedSun = false; }
set { m_FixedSun = value; }
}
private double m_SunPosition = 0.0;
public double SunPosition
{
get { return m_SunPosition; }
//set { m_SunPosition = value; }
set { m_SunPosition = 0; }
set { m_SunPosition = value; }
}
private bool m_AllowVoice = true;
@ -205,7 +202,7 @@ namespace OpenSim.Framework
}
private bool m_TaxFree = false;
public bool TaxFree // this is now !AllowAccessOverride, keeping same name to reuse DB entries
public bool TaxFree // this is now AllowAccessOverride, keeping same name to reuse DB entries
{
get { return m_TaxFree; }
set { m_TaxFree = value; }
@ -240,13 +237,6 @@ namespace OpenSim.Framework
set { m_DenyMinors = value; }
}
private bool m_AllowEnviromentOverride = false; //keep the mispell so not to go change the dbs
public bool AllowEnvironmentOverride
{
get { return m_AllowEnviromentOverride; }
set { m_AllowEnviromentOverride = value; }
}
// All those lists...
//
private List<UUID> l_EstateManagers = new List<UUID>();

View File

@ -1,291 +0,0 @@
/*
* Copyright (c) 2008, openmetaverse.org, http://opensimulator.org/
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Neither the name of the openmetaverse.org nor the names
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Timers;
using System.Threading;
using System.Collections.Generic;
using Timer = System.Timers.Timer;
namespace OpenSim.Framework
{
public class ExpiringKey<Tkey1> : IDisposable
{
private Dictionary<Tkey1, int> m_dictionary;
private ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();
private readonly double m_startTS;
private readonly int expire;
private Timer m_purgeTimer;
public ExpiringKey(int expireTimeinMS)
{
m_dictionary = new Dictionary<Tkey1, int>();
m_startTS = Util.GetTimeStampMS();
expire = expireTimeinMS;
if(expire < 500)
expire = 500;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private void SetTimer()
{
if (m_purgeTimer == null)
{
m_purgeTimer = new Timer()
{
Interval = expire,
AutoReset = false // time drift is not a issue.
};
m_purgeTimer.Elapsed += Purge;
m_purgeTimer.Start();
}
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
private void DisposeTimer()
{
if (m_purgeTimer != null)
{
m_purgeTimer.Stop();
m_purgeTimer.Dispose();
m_purgeTimer = null;
}
}
~ExpiringKey()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (m_rwLock != null)
{
m_rwLock.Dispose();
m_rwLock = null;
DisposeTimer();
}
}
private void Purge(object source, ElapsedEventArgs e)
{
if (m_dictionary.Count == 0)
{
DisposeTimer();
return;
}
bool gotLock = false;
int now = (int)(Util.GetTimeStampMS() - m_startTS);
try
{
try { }
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
}
List<Tkey1> expired = new List<Tkey1>(m_dictionary.Count);
foreach(KeyValuePair<Tkey1,int> kvp in m_dictionary)
{
if(kvp.Value < now)
expired.Add(kvp.Key);
}
foreach(Tkey1 key in expired)
m_dictionary.Remove(key);
if(m_dictionary.Count == 0)
DisposeTimer();
else
m_purgeTimer.Start();
}
finally
{
if (gotLock)
m_rwLock.ExitWriteLock();
}
}
public void Add(Tkey1 key)
{
bool gotLock = false;
int now = (int)(Util.GetTimeStampMS() - m_startTS) + expire;
try
{
// Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
// the acquision inside the main try. The inner finally block is needed because thread aborts cannot
// interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try { }
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
}
m_dictionary[key] = now;
SetTimer();
}
finally
{
if (gotLock)
m_rwLock.ExitWriteLock();
}
}
public void Add(Tkey1 key, int expireMS)
{
bool gotLock = false;
int now;
if (expireMS > 500)
now = (int)(Util.GetTimeStampMS() - m_startTS) + expire;
else
now = (int)(Util.GetTimeStampMS() - m_startTS) + 500;
try
{
// Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
// the acquision inside the main try. The inner finally block is needed because thread aborts cannot
// interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try { }
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
}
m_dictionary[key] = now;
SetTimer();
}
finally
{
if (gotLock)
m_rwLock.ExitWriteLock();
}
}
public bool Remove(Tkey1 key)
{
bool success;
bool gotLock = false;
try
{
// Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
// the acquision inside the main try. The inner finally block is needed because thread aborts cannot
// interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try {}
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
}
success = m_dictionary.Remove(key);
if(m_dictionary.Count == 0)
DisposeTimer();
}
finally
{
if (gotLock)
m_rwLock.ExitWriteLock();
}
return success;
}
public void Clear()
{
bool gotLock = false;
try
{
// Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
// the acquision inside the main try. The inner finally block is needed because thread aborts cannot
// interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try {}
finally
{
m_rwLock.EnterWriteLock();
gotLock = true;
m_dictionary.Clear();
DisposeTimer();
}
}
finally
{
if (gotLock)
m_rwLock.ExitWriteLock();
}
}
public int Count
{
get { return m_dictionary.Count; }
}
public bool ContainsKey(Tkey1 key)
{
return m_dictionary.ContainsKey(key);
}
public bool TryGetValue(Tkey1 key, out int value)
{
bool success;
bool gotLock = false;
try
{
// Avoid an asynchronous Thread.Abort() from possibly never existing an acquired lock by placing
// the acquision inside the main try. The inner finally block is needed because thread aborts cannot
// interrupt code in these blocks (hence gotLock is guaranteed to be set correctly).
try {}
finally
{
m_rwLock.EnterReadLock();
gotLock = true;
}
success = m_dictionary.TryGetValue(key, out value);
}
finally
{
if (gotLock)
m_rwLock.ExitReadLock();
}
return success;
}
}
}

View File

@ -35,7 +35,7 @@ namespace OpenSim.Framework
/// Cache the specified asset.
/// </summary>
/// <param name='asset'></param>
void Cache(AssetBase asset, bool replace = false);
void Cache(AssetBase asset);
/// <summary>
/// Cache that the specified asset wasn't found.

View File

@ -221,9 +221,7 @@ namespace OpenSim.Framework
public delegate void AddNewPrim(
UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape, byte bypassRaycast, Vector3 RayStart,
UUID RayTargetID,
byte RayEndIsIntersection, uint addflags);
public delegate void AgentDataUpdate(IClientAPI remoteClient, UUID itemID, UUID ownerID);
byte RayEndIsIntersection);
public delegate void RequestGodlikePowers(
UUID AgentID, UUID SessionID, UUID token, bool GodLike);
@ -254,7 +252,7 @@ namespace OpenSim.Framework
public delegate void PurgeInventoryDescendents(
IClientAPI remoteClient, UUID folderID);
public delegate void FetchInventory(IClientAPI remoteClient, UUID[] items, UUID[] owner);
public delegate void FetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID);
public delegate void RequestTaskInventory(IClientAPI remoteClient, uint localID);
@ -848,7 +846,7 @@ namespace OpenSim.Framework
event Action<IClientAPI> OnRequestAvatarsData;
event AddNewPrim OnAddPrim;
event AgentDataUpdate OnAgentDataUpdateRequest;
event FetchInventory OnAgentDataUpdateRequest;
event TeleportLocationRequest OnSetStartLocationRequest;
event RequestGodlikePowers OnRequestGodlikePowers;
@ -1207,10 +1205,10 @@ namespace OpenSim.Framework
void FlushPrimUpdates();
void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
List<InventoryFolderBase> folders, int version, int descendents,
bool fetchFolders, bool fetchItems);
List<InventoryFolderBase> folders, int version, bool fetchFolders,
bool fetchItems);
void SendInventoryItemDetails(InventoryItemBase[] items);
void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item);
/// <summary>
/// Tell the client that we have created the item it requested.
@ -1250,7 +1248,7 @@ namespace OpenSim.Framework
int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice,
float TeleportPriceExponent);
void SendAvatarPickerReply(UUID QueryID, List<UserData> users);
void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data);
void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers,
string groupname, string grouptitle);
@ -1286,8 +1284,20 @@ namespace OpenSim.Framework
void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
string[] buttonlabels);
void SendViewerTime(Vector3 sunDir, float sunphase);
/// <summary>
/// Update the client as to where the sun is currently located.
/// </summary>
/// <param name="sunPos"></param>
/// <param name="sunVel"></param>
/// <param name="CurrentTime">Seconds since Unix Epoch 01/01/1970 00:00:00</param>
/// <param name="SecondsPerSunCycle"></param>
/// <param name="SecondsPerYear"></param>
/// <param name="OrbitalPosition">The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView</param>
void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear,
float OrbitalPosition);
void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks);
void SendViewerTime(int phase);
void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] membershipType, string flAbout,
uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID);

View File

@ -99,6 +99,5 @@ namespace OpenSim.Region.Framework.Interfaces
void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay);
void ClearAllEnvironments();
}
}

View File

@ -73,7 +73,6 @@ namespace OpenSim.Framework
ILandObject Copy();
void SendLandUpdateToAvatarsOverMe();
void SendLandUpdateToAvatars();
void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client);
bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay);
@ -172,8 +171,6 @@ namespace OpenSim.Framework
void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
void StoreEnvironment(ViewerEnvironment VEnv);
/// <summary>
/// Set the media url for this land parcel

View File

@ -51,9 +51,9 @@ namespace OpenSim.Framework
public const string LLSDEmpty = "<llsd><map /></llsd>";
// got tired of creating a stringbuilder all the time;
public static StringBuilder Start(int size = 4096, bool addxmlversion = false)
public static StringBuilder Start(int size = 256, bool addxmlversion = false)
{
StringBuilder sb = osStringBuilderCache.Acquire(size);
StringBuilder sb = new StringBuilder(size);
if(addxmlversion)
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd>"); // legacy llsd xml name still valid
else
@ -69,13 +69,7 @@ namespace OpenSim.Framework
public static string End(StringBuilder sb)
{
sb.Append("</llsd>");
return osStringBuilderCache.GetStringAndRelease(sb);
}
public static byte[] EndToNBBytes(StringBuilder sb)
{
sb.Append("</llsd>");
return Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb));
return sb.ToString();
}
// map == a list of key value pairs
@ -126,7 +120,7 @@ namespace OpenSim.Framework
if(e)
sb.Append("<boolean>1</boolean>");
else
sb.Append("<boolean>0</boolean>");
sb.Append("<boolean />");
}
public static void AddElem(byte e, StringBuilder sb)
@ -148,22 +142,7 @@ namespace OpenSim.Framework
else
{
sb.Append("<binary>"); // encode64 is default
base64Encode(e, sb);
sb.Append("</binary>");
}
}
public static void AddElem(byte[] e, int start, int length, StringBuilder sb)
{
if (start + length >= e.Length)
length = e.Length - start;
if (e == null || e.Length == 0 || length <= 0)
sb.Append("binary />");
else
{
sb.Append("<binary>"); // encode64 is default
base64Encode(e, start, length, sb);
sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None));
sb.Append("</binary>");
}
}
@ -193,7 +172,7 @@ namespace OpenSim.Framework
public static void AddElem(float e, StringBuilder sb)
{
if(e == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -207,7 +186,7 @@ namespace OpenSim.Framework
sb.Append("<array>");
if(e.X == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -216,7 +195,7 @@ namespace OpenSim.Framework
}
if(e.Y == 0)
sb.Append("<real>0</real></array>");
sb.Append("<real /></array>");
else
{
sb.Append("<real>");
@ -230,7 +209,7 @@ namespace OpenSim.Framework
sb.Append("<array>");
if(e.X == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -239,7 +218,7 @@ namespace OpenSim.Framework
}
if(e.Y == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -248,7 +227,7 @@ namespace OpenSim.Framework
}
if(e.Z == 0)
sb.Append("<real>0</real></array>");
sb.Append("<real /></array>");
else
{
sb.Append("<real>");
@ -262,7 +241,7 @@ namespace OpenSim.Framework
sb.Append("<array><key>x</key>");
if(e.X == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -271,7 +250,7 @@ namespace OpenSim.Framework
}
if(e.Y == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -279,7 +258,7 @@ namespace OpenSim.Framework
sb.Append("</real>");
}
if(e.Z == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -288,7 +267,7 @@ namespace OpenSim.Framework
}
if(e.W == 0)
sb.Append("<real>0</real></array>");
sb.Append("<real /></array>");
else
{
sb.Append("<real>");
@ -300,7 +279,7 @@ namespace OpenSim.Framework
public static void AddElem(double e, StringBuilder sb)
{
if(e == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -316,7 +295,7 @@ namespace OpenSim.Framework
else
{
sb.Append("<uuid>");
EscapeToXML(e.ToString(), sb);
EscapeToXML(e.ToString(), sb);
sb.Append("</uuid>");
}
}
@ -338,7 +317,7 @@ namespace OpenSim.Framework
if(String.IsNullOrEmpty(e))
return;
sb.Append(e);
sb.Append(e);
}
public static void AddElem(Uri e, StringBuilder sb)
@ -441,7 +420,7 @@ namespace OpenSim.Framework
if(e)
sb.Append("<boolean>1</boolean>");
else
sb.Append("<boolean>0</boolean>");
sb.Append("<boolean />");
}
public static void AddElem(string name, byte e, StringBuilder sb)
@ -466,31 +445,12 @@ namespace OpenSim.Framework
sb.Append(name);
sb.Append("</key>");
if (e == null || e.Length == 0)
if(e == null || e.Length == 0)
sb.Append("binary />");
else
{
sb.Append("<binary>"); // encode64 is default
base64Encode(e, sb);
sb.Append("</binary>");
}
}
public static void AddElem(string name, byte[] e, int start, int length, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if (start + length >= e.Length)
length = e.Length - start;
if (e == null || e.Length == 0 || length <= 0)
sb.Append("binary />");
else
{
sb.Append("<binary>"); // encode64 is default
base64Encode(e, start, length, sb);
sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None));
sb.Append("</binary>");
}
}
@ -528,7 +488,7 @@ namespace OpenSim.Framework
sb.Append("</key>");
if(e == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -544,7 +504,7 @@ namespace OpenSim.Framework
sb.Append("</key><array>>");
if(e.X == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -553,7 +513,7 @@ namespace OpenSim.Framework
}
if(e.Y == 0)
sb.Append("<real>0</real></array>");
sb.Append("<real /></array>");
else
{
sb.Append("<real>");
@ -569,7 +529,7 @@ namespace OpenSim.Framework
sb.Append("</key><array>");
if(e.X == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -578,7 +538,7 @@ namespace OpenSim.Framework
}
if(e.Y == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -587,7 +547,7 @@ namespace OpenSim.Framework
}
if(e.Z == 0)
sb.Append("<real>0</real></array>");
sb.Append("<real /></array>");
else
{
sb.Append("<real>");
@ -603,7 +563,7 @@ namespace OpenSim.Framework
sb.Append("</key><array>");
if(e.X == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -612,7 +572,7 @@ namespace OpenSim.Framework
}
if(e.Y == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -620,7 +580,7 @@ namespace OpenSim.Framework
sb.Append("</real>");
}
if(e.Z == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -629,7 +589,7 @@ namespace OpenSim.Framework
}
if(e.W == 0)
sb.Append("<real>0</real></array>");
sb.Append("<real /></array>");
else
{
sb.Append("<real>");
@ -645,7 +605,7 @@ namespace OpenSim.Framework
sb.Append("</key>");
if(e == 0)
sb.Append("<real>0</real>");
sb.Append("<real />");
else
{
sb.Append("<real>");
@ -764,8 +724,11 @@ namespace OpenSim.Framework
public static void EscapeToXML(string s, StringBuilder sb)
{
int i;
char c;
for (int i = 0; i < s.Length; ++i)
int len = s.Length;
for (i = 0; i < len; i++)
{
c = s[i];
switch (c)
@ -817,97 +780,5 @@ namespace OpenSim.Framework
(byte)value
};
}
static readonly char[] base64Chars = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
'8','9','+','/'};
public static unsafe void base64Encode(byte[] data, StringBuilder sb)
{
int lenMod3 = data.Length % 3;
int len = data.Length - lenMod3;
fixed (byte* d = data)
{
fixed (char* b64 = base64Chars)
{
int i = 0;
while(i < len)
{
sb.Append(b64[d[i] >> 2]);
sb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]);
sb.Append(b64[((d[i + 1] & 0x0f) << 2) | ((d[i + 2] & 0xc0) >> 6)]);
sb.Append(b64[d[i + 2] & 0x3f]);
i += 3;
}
switch (lenMod3)
{
case 2:
{
i = len;
sb.Append(b64[d[i] >> 2]);
sb.Append(b64[((d[i] & 0x03) << 4) | ((d[i + 1] & 0xf0) >> 4)]);
sb.Append(b64[((d[i + 1] & 0x0f) << 2)]);
sb.Append('=');
break;
}
case 1:
{
i = len;
sb.Append(b64[d[i] >> 2]);
sb.Append(b64[(d[i] & 0x03) << 4]);
sb.Append("==");
break;
}
}
}
}
}
public static unsafe void base64Encode(byte[] data, int start, int length, StringBuilder sb)
{
int lenMod3 = length % 3;
int len = start + (length - lenMod3);
fixed (byte* d = data)
{
fixed (char* b64 = base64Chars)
{
int i = start;
while(i < len)
{
sb.Append(b64[(d[i] & 0xfc) >> 2]);
sb.Append(b64[((d[i] & 0x03) << 4) | (d[i + 1] >> 4)]);
sb.Append(b64[((d[i + 1] & 0x0f) << 2) | (d[i + 2] >> 6)]);
sb.Append(b64[d[i + 2] & 0x3f]);
i += 3;
}
switch (lenMod3)
{
case 2:
{
i = len;
sb.Append(b64[d[i] >> 2]);
sb.Append(b64[((d[i] & 0x03) << 4) | (d[i + 1] >> 4)]);
sb.Append(b64[((d[i + 1] & 0x0f) << 2)]);
sb.Append('=');
break;
}
case 1:
{
i = len;
sb.Append(b64[d[i] >> 2]);
sb.Append(b64[(d[i] & 0x03) << 4]);
sb.Append("==");
break;
}
}
}
}
}
}
}

View File

@ -732,11 +732,6 @@ namespace OpenSim.Framework
}
}
public int EnvironmentVersion = -1;
[XmlIgnore] //this needs to be added by hand
public ViewerEnvironment Environment { get; set;}
public LandData()
{
_globalID = UUID.Random();
@ -744,8 +739,6 @@ namespace OpenSim.Framework
AnyAVSounds = true;
GroupAVSounds = true;
LastDwellTimeMS = Util.GetTimeStampMS();
EnvironmentVersion = -1;
Environment = null;
}
/// <summary>
@ -811,17 +804,6 @@ namespace OpenSim.Framework
landData._parcelAccessList.Add(newEntry);
}
if (Environment == null)
{
landData.Environment = null;
landData.EnvironmentVersion = -1;
}
else
{
landData.Environment = Environment.Clone();
landData.EnvironmentVersion = EnvironmentVersion;
}
return landData;
}

View File

@ -131,15 +131,7 @@ namespace OpenSim.Framework.Monitoring
finally
{
if(m_cancelSource != null)
{
m_cancelSource.Dispose();
m_cancelSource = null;
}
if (m_jobQueue != null)
{
m_jobQueue.Dispose();
m_jobQueue = null;
}
}
}
}
@ -246,13 +238,13 @@ namespace OpenSim.Framework.Monitoring
break;
}
}
catch (OperationCanceledException)
catch(ObjectDisposedException)
{
m_log.DebugFormat("[JobEngine] {0} Canceled ignoring {1} jobs in queue",
Name, m_jobQueue.Count);
m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue",
Name,m_jobQueue.Count);
break;
}
catch
catch(OperationCanceledException)
{
break;
}
@ -274,7 +266,6 @@ namespace OpenSim.Framework.Monitoring
if(LogLevel >= 1)
m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,m_currentJob.Name);
m_currentJob.Action = null;
m_currentJob = null;
}
}
@ -301,7 +292,7 @@ namespace OpenSim.Framework.Monitoring
/// <summary>
/// Action to perform when this job is processed.
/// </summary>
public Action Action { get; set; }
public Action Action { get; private set; }
private Job(string name, string commonId, Action action)
{

View File

@ -1242,7 +1242,7 @@ namespace OpenSim.Framework
byte extraParamCount = data[0];
int i = 1;
for (int k = 0; k < extraParamCount; ++k)
for (int k = 0; k < extraParamCount; k++)
{
byte epType = data[i];
i += 6;

View File

@ -40,12 +40,69 @@ using OpenMetaverse.StructuredData;
namespace OpenSim.Framework
{
[Serializable]
public class RegionLightShareData : ICloneable
{
public bool valid = false;
public UUID regionID = UUID.Zero;
public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f);
public float waterFogDensityExponent = 4.0f;
public float underwaterFogModifier = 0.25f;
public Vector3 reflectionWaveletScale = new Vector3(2.0f,2.0f,2.0f);
public float fresnelScale = 0.40f;
public float fresnelOffset = 0.50f;
public float refractScaleAbove = 0.03f;
public float refractScaleBelow = 0.20f;
public float blurMultiplier = 0.040f;
public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f);
public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f);
public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4");
public Vector4 horizon = new Vector4(0.25f, 0.25f, 0.32f, 0.32f);
public float hazeHorizon = 0.19f;
public Vector4 blueDensity = new Vector4(0.12f, 0.22f, 0.38f, 0.38f);
public float hazeDensity = 0.70f;
public float densityMultiplier = 0.18f;
public float distanceMultiplier = 0.8f;
public UInt16 maxAltitude = 1605;
public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f);
public float sunMoonPosition = 0.317f;
public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f);
public float eastAngle = 0.0f;
public float sunGlowFocus = 0.10f;
public float sunGlowSize = 1.75f;
public float sceneGamma = 1.0f;
public float starBrightness = 0.0f;
public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f);
public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f);
public float cloudCoverage = 0.27f;
public float cloudScale = 0.42f;
public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f);
public float cloudScrollX = 0.20f;
public bool cloudScrollXLock = false;
public float cloudScrollY = 0.01f;
public bool cloudScrollYLock = false;
public bool drawClassicClouds = true;
public delegate void SaveDelegate(RegionLightShareData wl);
public event SaveDelegate OnSave;
public void Save()
{
if (OnSave != null)
OnSave(this);
}
public object Clone()
{
return this.MemberwiseClone(); // call clone method
}
}
public class RegionInfo
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[REGION INFO]";
public bool commFailTF = false;
public ConfigurationMember configMember;
public string DataStore = String.Empty;
@ -77,6 +134,7 @@ namespace OpenSim.Framework
private int m_maxPrimsPerUser = -1;
private int m_linksetCapacity = 0;
private string m_regionType = String.Empty;
private RegionLightShareData m_windlight = new RegionLightShareData();
protected uint m_httpPort;
protected string m_serverURI;
protected string m_regionName = String.Empty;
@ -122,6 +180,7 @@ namespace OpenSim.Framework
private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
public UUID CacheID { get; set;}
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
// MT: Yes. Estates can't span trust boundaries. Therefore, it can be
@ -138,6 +197,8 @@ namespace OpenSim.Framework
public RegionInfo(string description, string filename, bool skipConsoleConfig, IConfigSource configSource, string configName)
{
// m_configSource = configSource;
CacheID = UUID.Random();
if (filename.ToLower().EndsWith(".ini"))
{
if (!File.Exists(filename)) // New region config request
@ -164,6 +225,7 @@ namespace OpenSim.Framework
source.Save(filename);
RegionFile = filename;
return;
}
@ -195,6 +257,7 @@ namespace OpenSim.Framework
ReadNiniConfig(source, name);
m_serverURI = string.Empty;
CacheID = UUID.Random();
}
public RegionInfo(uint legacyRegionLocX, uint legacyRegionLocY, IPEndPoint internalEndPoint, string externalUri)
@ -206,11 +269,13 @@ namespace OpenSim.Framework
m_internalEndPoint = internalEndPoint;
m_externalHostName = externalUri;
m_serverURI = string.Empty;
CacheID = UUID.Random();
}
public RegionInfo()
{
m_serverURI = string.Empty;
CacheID = UUID.Random();
}
public EstateSettings EstateSettings
@ -243,6 +308,21 @@ namespace OpenSim.Framework
set { m_regionSettings = value; }
}
public RegionLightShareData WindlightSettings
{
get
{
if (m_windlight == null)
{
m_windlight = new RegionLightShareData();
}
return m_windlight;
}
set { m_windlight = value; }
}
public float NonphysPrimMin
{
get { return m_nonphysPrimMin; }

View File

@ -121,15 +121,15 @@ namespace OpenSim.Framework
}
private UUID m_RegionUUID = UUID.Zero;
public UUID RegionUUID
{
get { return m_RegionUUID; }
set { m_RegionUUID = value; }
}
public UUID CacheID { get; set; } = UUID.Random();
private bool m_BlockTerraform = false;
public bool BlockTerraform
{
get { return m_BlockTerraform; }
@ -137,6 +137,7 @@ namespace OpenSim.Framework
}
private bool m_BlockFly = false;
public bool BlockFly
{
get { return m_BlockFly; }
@ -144,6 +145,7 @@ namespace OpenSim.Framework
}
private bool m_AllowDamage = false;
public bool AllowDamage
{
get { return m_AllowDamage; }
@ -151,6 +153,7 @@ namespace OpenSim.Framework
}
private bool m_RestrictPushing = false;
public bool RestrictPushing
{
get { return m_RestrictPushing; }
@ -158,6 +161,7 @@ namespace OpenSim.Framework
}
private bool m_AllowLandResell = true;
public bool AllowLandResell
{
get { return m_AllowLandResell; }
@ -165,6 +169,7 @@ namespace OpenSim.Framework
}
private bool m_AllowLandJoinDivide = true;
public bool AllowLandJoinDivide
{
get { return m_AllowLandJoinDivide; }
@ -172,6 +177,7 @@ namespace OpenSim.Framework
}
private bool m_BlockShowInSearch = false;
public bool BlockShowInSearch
{
get { return m_BlockShowInSearch; }
@ -179,6 +185,7 @@ namespace OpenSim.Framework
}
private int m_AgentLimit = 40;
public int AgentLimit
{
get { return m_AgentLimit; }
@ -186,6 +193,7 @@ namespace OpenSim.Framework
}
private double m_ObjectBonus = 1.0;
public double ObjectBonus
{
get { return m_ObjectBonus; }
@ -193,6 +201,7 @@ namespace OpenSim.Framework
}
private int m_Maturity = 0;
public int Maturity
{
get { return m_Maturity; }
@ -200,6 +209,7 @@ namespace OpenSim.Framework
}
private bool m_DisableScripts = false;
public bool DisableScripts
{
get { return m_DisableScripts; }
@ -207,6 +217,7 @@ namespace OpenSim.Framework
}
private bool m_DisableCollisions = false;
public bool DisableCollisions
{
get { return m_DisableCollisions; }
@ -214,6 +225,7 @@ namespace OpenSim.Framework
}
private bool m_DisablePhysics = false;
public bool DisablePhysics
{
get { return m_DisablePhysics; }
@ -277,6 +289,7 @@ namespace OpenSim.Framework
}
private double m_Elevation1NW = 10;
public double Elevation1NW
{
get { return m_Elevation1NW; }
@ -284,6 +297,7 @@ namespace OpenSim.Framework
}
private double m_Elevation2NW = 60;
public double Elevation2NW
{
get { return m_Elevation2NW; }
@ -291,6 +305,7 @@ namespace OpenSim.Framework
}
private double m_Elevation1NE = 10;
public double Elevation1NE
{
get { return m_Elevation1NE; }
@ -298,6 +313,7 @@ namespace OpenSim.Framework
}
private double m_Elevation2NE = 60;
public double Elevation2NE
{
get { return m_Elevation2NE; }
@ -305,6 +321,7 @@ namespace OpenSim.Framework
}
private double m_Elevation1SE = 10;
public double Elevation1SE
{
get { return m_Elevation1SE; }
@ -312,6 +329,7 @@ namespace OpenSim.Framework
}
private double m_Elevation2SE = 60;
public double Elevation2SE
{
get { return m_Elevation2SE; }
@ -319,6 +337,7 @@ namespace OpenSim.Framework
}
private double m_Elevation1SW = 10;
public double Elevation1SW
{
get { return m_Elevation1SW; }
@ -326,6 +345,7 @@ namespace OpenSim.Framework
}
private double m_Elevation2SW = 60;
public double Elevation2SW
{
get { return m_Elevation2SW; }
@ -333,6 +353,7 @@ namespace OpenSim.Framework
}
private double m_WaterHeight = 20;
public double WaterHeight
{
get { return m_WaterHeight; }
@ -340,6 +361,7 @@ namespace OpenSim.Framework
}
private double m_TerrainRaiseLimit = 100;
public double TerrainRaiseLimit
{
get { return m_TerrainRaiseLimit; }
@ -347,6 +369,7 @@ namespace OpenSim.Framework
}
private double m_TerrainLowerLimit = -100;
public double TerrainLowerLimit
{
get { return m_TerrainLowerLimit; }
@ -354,6 +377,7 @@ namespace OpenSim.Framework
}
private bool m_UseEstateSun = true;
public bool UseEstateSun
{
get { return m_UseEstateSun; }
@ -361,19 +385,23 @@ namespace OpenSim.Framework
}
private bool m_Sandbox = false;
public bool Sandbox
{
get { return m_Sandbox; }
set { m_Sandbox = value; }
}
private Vector3 m_SunVector;
public Vector3 SunVector
{
get { return Vector3.Zero; }
set { }
get { return m_SunVector; }
set { m_SunVector = value; }
}
private UUID m_ParcelImageID;
public UUID ParcelImageID
{
get { return m_ParcelImageID; }
@ -381,22 +409,27 @@ namespace OpenSim.Framework
}
private UUID m_TerrainImageID;
public UUID TerrainImageID
{
get { return m_TerrainImageID; }
set { m_TerrainImageID = value; }
}
private bool m_FixedSun = false;
public bool FixedSun
{
get { return false; }
set { }
get { return m_FixedSun; }
set { m_FixedSun = value; }
}
private double m_SunPosition = 0.0;
public double SunPosition
{
get { return 0; }
set { }
get { return m_SunPosition; }
set { m_SunPosition = value; }
}
private UUID m_Covenant = UUID.Zero;

View File

@ -32,7 +32,6 @@ using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using log4net;
@ -118,7 +117,8 @@ namespace OpenSim.Framework
/// <summary>
/// Default Buffer size of a block requested from the web-server
/// </summary>
private const int BufferSize = 4 * 4096; // Read blocks of 4 * 4 KB.
private const int BufferSize = 4096; // Read blocks of 4 KB.
/// <summary>
/// if an exception occours during async processing, we need to save it, so it can be
@ -181,7 +181,10 @@ namespace OpenSim.Framework
/// <param name="element">path entry</param>
public void AddResourcePath(string element)
{
_pathElements.Add(Util.TrimEndSlash(element));
if (isSlashed(element))
_pathElements.Add(element.Substring(0, element.Length - 1));
else
_pathElements.Add(element);
}
/// <summary>
@ -234,6 +237,16 @@ namespace OpenSim.Framework
set { _method = value; }
}
/// <summary>
/// True if string contains a trailing slash '/'
/// </summary>
/// <param name="s">string to be examined</param>
/// <returns>true if slash is present</returns>
private static bool isSlashed(string s)
{
return s.Substring(s.Length - 1, 1) == "/";
}
/// <summary>
/// Build a Uri based on the initial Url, path elements and parameters
/// </summary>
@ -326,8 +339,9 @@ namespace OpenSim.Framework
lock (_lock)
{
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
_request.ContentType = "application/xml";
_request.Timeout = 90000;
_request.Timeout = 200000;
_request.Method = RequestMethod;
_asyncException = null;
if (auth != null)
@ -337,6 +351,8 @@ namespace OpenSim.Framework
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
try
{
using (_response = (HttpWebResponse) _request.GetResponse())
@ -349,6 +365,12 @@ namespace OpenSim.Framework
_resource.Write(_readbuf, 0, length);
length = src.Read(_readbuf, 0, BufferSize);
}
// TODO! Implement timeout, without killing the server
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
// _allDone.WaitOne();
}
}
}
@ -369,6 +391,7 @@ namespace OpenSim.Framework
return null;
}
if (_asyncException != null)
throw _asyncException;
@ -385,53 +408,81 @@ namespace OpenSim.Framework
}
}
// just post data, ignoring result
public async Task AsyncPOSTRequest(byte[] src, IServiceAuth auth)
public Stream Request(Stream src, IServiceAuth auth)
{
_request = (HttpWebRequest)WebRequest.Create(buildUri());
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
_request.ContentType = "application/xml";
_request.Timeout = 90000;
_request.Method = "POST";
_request.Method = RequestMethod;
_asyncException = null;
_request.ContentLength = src.Length;
if (auth != null)
auth.AddAuthorization(_request.Headers);
src.Seek(0, SeekOrigin.Begin);
int reqnum = WebUtil.RequestNumber++;
if (WebUtil.DebugLevel >= 3)
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src);
try
{
using (Stream dst = _request.GetRequestStream())
{
await dst.WriteAsync(src, 0, src.Length).ConfigureAwait(false);
}
// m_log.Debug("[REST]: GetRequestStream is ok");
using(HttpWebResponse response = (HttpWebResponse)await _request.GetResponseAsync().ConfigureAwait(false))
{
if (WebUtil.DebugLevel >= 5)
byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024);
// m_log.Debug("[REST]: First Read is ok");
while (length > 0)
{
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
string responseStr = await reader.ReadToEndAsync().ConfigureAwait(false);
WebUtil.LogResponseDetail(reqnum, responseStr);
}
}
dst.Write(buf, 0, length);
length = src.Read(buf, 0, 1024);
}
}
_response = (HttpWebResponse)_request.GetResponse();
}
catch (WebException e)
{
m_log.WarnFormat("[REST]: AsyncPOST {0} failed with status {1} and message {2}",
_request.RequestUri, e.Status, e.Message);
return;
m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
RequestMethod, _request.RequestUri, e.Status, e.Message);
return null;
}
catch (Exception e)
{
m_log.WarnFormat("[REST]: AsyncPOST {0} failed with exception {1} {2}",
_request.RequestUri, e.Message, e.StackTrace);
return;
m_log.WarnFormat(
"[REST]: Request {0} {1} failed with exception {2} {3}",
RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
return null;
}
if (WebUtil.DebugLevel >= 5)
{
using (Stream responseStream = _response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
string responseStr = reader.ReadToEnd();
WebUtil.LogResponseDetail(reqnum, responseStr);
}
}
}
if (_response != null)
_response.Close();
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
// TODO! Implement timeout, without killing the server
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
return null;
}
#region Async Invocation

View File

@ -28,7 +28,6 @@
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace OpenSim.Framework
{
@ -45,6 +44,7 @@ namespace OpenSim.Framework
Material = -2
}
#region SL / file extension / content-type conversions
/// <summary>
@ -190,56 +190,6 @@ namespace OpenSim.Framework
private static Dictionary<sbyte, string> inventory2Content;
private static Dictionary<string, sbyte> content2Asset;
private static Dictionary<string, sbyte> content2Inventory;
private static Dictionary<string, AssetType> name2Asset = new Dictionary<string, AssetType>()
{
{"texture", AssetType.Texture },
{"sound", AssetType.Sound},
{"callcard", AssetType.CallingCard},
{"landmark", AssetType.Landmark},
{"script", (AssetType)4},
{"clothing", AssetType.Clothing},
{"object", AssetType.Object},
{"notecard", AssetType.Notecard},
{"category", AssetType.Folder},
{"lsltext", AssetType.LSLText},
{"lslbyte", AssetType.LSLBytecode},
{"txtr_tga", AssetType.TextureTGA},
{"bodypart", AssetType.Bodypart},
{"snd_wav", AssetType.SoundWAV},
{"img_tga", AssetType.ImageTGA},
{"jpeg", AssetType.ImageJPEG},
{"animatn", AssetType.Animation},
{"gesture", AssetType.Gesture},
{"simstate", AssetType.Simstate},
{"mesh", AssetType.Mesh},
{"settings", AssetType.Settings}
};
private static Dictionary<string, FolderType> name2Inventory = new Dictionary<string, FolderType>()
{
{"texture", FolderType.Texture},
{"sound", FolderType.Sound},
{"callcard", FolderType.CallingCard},
{"landmark", FolderType.Landmark},
{"script", (FolderType)4},
{"clothing", FolderType.Clothing},
{"object", FolderType.Object},
{"notecard", FolderType.Notecard},
{"root", FolderType.Root},
{"lsltext", FolderType.LSLText},
{"bodypart", FolderType.BodyPart},
{"trash", FolderType.Trash},
{"snapshot", FolderType.Snapshot},
{"lostandfound", FolderType.LostAndFound},
{"animatn", FolderType.Animation},
{"gesture", FolderType.Gesture},
{"favorites", FolderType.Favorites},
{"currentoutfit", FolderType.CurrentOutfit},
{"outfit", FolderType.Outfit},
{"myoutfits", FolderType.MyOutfits},
{"mesh", FolderType.Mesh},
{"settings", FolderType.Settings},
{"suitcase", FolderType.Suitcase}
};
static SLUtil()
{
@ -277,20 +227,6 @@ namespace OpenSim.Framework
}
}
public static AssetType SLAssetName2Type(string name)
{
if (name2Asset.TryGetValue(name, out AssetType type))
return type;
return AssetType.Unknown;
}
public static FolderType SLInvName2Type(string name)
{
if (name2Inventory.TryGetValue(name, out FolderType type))
return type;
return FolderType.None;
}
public static string SLAssetTypeToContentType(int assetType)
{
string contentType;
@ -333,364 +269,270 @@ namespace OpenSim.Framework
#endregion SL / file extension / content-type conversions
static char[] seps = new char[] { '\t', '\n' };
static char[] stringseps = new char[] { '|', '\n' };
static byte[] moronize = new byte[16]
private class NotecardReader
{
60, 17, 94, 81, 4, 244, 82, 60, 159, 166, 152, 175, 241, 3, 71, 48
};
private string rawInput;
private int lineNumber;
static int getField(string note, int start, string name, bool isString, out string value)
{
value = String.Empty;
int end = -1;
int limit = note.Length - start;
if (limit > 64)
limit = 64;
int indx = note.IndexOf(name, start, limit);
if (indx < 0)
return -1;
indx += name.Length + 1; // eat \t
limit = note.Length - indx - 2;
if (limit > 129)
limit = 129;
if (isString)
end = note.IndexOfAny(stringseps, indx, limit);
else
end = note.IndexOfAny(seps, indx, limit);
if (end < 0)
return -1;
value = note.Substring(indx, end - indx);
return end;
}
private static UUID deMoronize(UUID id)
{
byte[] data = new byte[16];
id.ToBytes(data,0);
for(int i = 0; i < 16; ++i)
data[i] ^= moronize[i];
return new UUID(data,0);
}
public static InventoryItemBase GetEmbeddedItem(byte[] data, UUID itemID)
{
if(data == null || data.Length < 300)
return null;
string note = Util.UTF8.GetString(data);
if (String.IsNullOrWhiteSpace(note))
return null;
// waste some time checking rigid versions
string version = note.Substring(0,21);
if (!version.Equals("Linden text version 2"))
return null;
version = note.Substring(24, 25);
if (!version.Equals("LLEmbeddedItems version 1"))
return null;
int indx = note.IndexOf(itemID.ToString(), 100);
if (indx < 0)
return null;
indx = note.IndexOf("permissions", indx, 100); // skip parentID
if (indx < 0)
return null;
string valuestr;
indx = getField(note, indx, "base_mask", false, out valuestr);
if (indx < 0)
return null;
if (!uint.TryParse(valuestr, NumberStyles.HexNumber, Culture.NumberFormatInfo, out uint basemask))
return null;
indx = getField(note, indx, "owner_mask", false, out valuestr);
if (indx < 0)
return null;
if (!uint.TryParse(valuestr, NumberStyles.HexNumber, Culture.NumberFormatInfo, out uint ownermask))
return null;
indx = getField(note, indx, "group_mask", false, out valuestr);
if (indx < 0)
return null;
if (!uint.TryParse(valuestr, NumberStyles.HexNumber, Culture.NumberFormatInfo, out uint groupmask))
return null;
indx = getField(note, indx, "everyone_mask", false, out valuestr);
if (indx < 0)
return null;
if (!uint.TryParse(valuestr, NumberStyles.HexNumber, Culture.NumberFormatInfo, out uint everyonemask))
return null;
indx = getField(note, indx, "next_owner_mask", false, out valuestr);
if (indx < 0)
return null;
if (!uint.TryParse(valuestr, NumberStyles.HexNumber, Culture.NumberFormatInfo, out uint nextownermask))
return null;
indx = getField(note, indx, "creator_id", false, out valuestr);
if (indx < 0)
return null;
if (!UUID.TryParse(valuestr, out UUID creatorID))
return null;
indx = getField(note, indx, "owner_id", false, out valuestr);
if (indx < 0)
return null;
if (!UUID.TryParse(valuestr, out UUID ownerID))
return null;
int limit = note.Length - indx;
if (limit > 120)
limit = 120;
indx = note.IndexOf('}', indx, limit); // last owner
if (indx < 0)
return null;
int curindx = indx;
UUID assetID = UUID.Zero;
indx = getField(note, indx, "asset_id", false, out valuestr);
if (indx < 0)
public int LineNumber
{
indx = getField(note, curindx, "shadow_id", false, out valuestr);
if (indx < 0)
return null;
if (!UUID.TryParse(valuestr, out assetID))
return null;
assetID = deMoronize(assetID);
}
else
{
if (!UUID.TryParse(valuestr, out assetID))
return null;
}
indx = getField(note, indx, "type", false, out valuestr);
if (indx < 0)
return null;
AssetType assetType = SLAssetName2Type(valuestr);
indx = getField(note, indx, "inv_type", false, out valuestr);
if (indx < 0)
return null;
FolderType invType = SLInvName2Type(valuestr);
indx = getField(note, indx, "flags", false, out valuestr);
if (indx < 0)
return null;
if (!uint.TryParse(valuestr, NumberStyles.HexNumber, Culture.NumberFormatInfo, out uint flags))
return null;
limit = note.Length - indx;
if (limit > 120)
limit = 120;
indx = note.IndexOf('}', indx, limit); // skip sale
if (indx < 0)
return null;
indx = getField(note, indx, "name", true, out valuestr);
if (indx < 0)
return null;
string name = valuestr;
indx = getField(note, indx, "desc", true, out valuestr);
if (indx < 0)
return null;
string desc = valuestr;
InventoryItemBase item = new InventoryItemBase();
item.AssetID = assetID;
item.AssetType = (sbyte)assetType;
item.BasePermissions = basemask;
item.CreationDate = Util.UnixTimeSinceEpoch();
item.CreatorData = "";
item.CreatorId = creatorID.ToString();
item.CurrentPermissions = ownermask;
item.Description = desc;
item.Flags = flags;
item.Folder = UUID.Zero;
item.GroupID = UUID.Zero;
item.GroupOwned = false;
item.GroupPermissions = groupmask;
item.InvType = (sbyte)invType;
item.Name = name;
item.NextPermissions = nextownermask;
item.Owner = ownerID;
item.SalePrice = 0;
item.SaleType = (byte)SaleType.Not;
item.ID = UUID.Random();
return item;
}
public static List<UUID> GetEmbeddedAssetIDs(byte[] data)
{
if (data == null || data.Length < 79)
return null;
string note = Util.UTF8.GetString(data);
if (String.IsNullOrWhiteSpace(note))
return null;
// waste some time checking rigid versions
string tmpStr = note.Substring(0, 21);
if (!tmpStr.Equals("Linden text version 2"))
return null;
tmpStr = note.Substring(24, 25);
if (!tmpStr.Equals("LLEmbeddedItems version 1"))
return null;
tmpStr = note.Substring(52,5);
if (!tmpStr.Equals("count"))
return null;
int limit = note.Length - 57 - 2;
if (limit > 8)
limit = 8;
int indx = note.IndexOfAny(seps, 57, limit);
if(indx < 0)
return null;
if (!int.TryParse(note.Substring(57, indx - 57), out int count))
return null;
List<UUID> ids = new List<UUID>();
while(count > 0)
{
string valuestr;
UUID assetID = UUID.Zero;
indx = note.IndexOf('}',indx); // skip to end of permissions
if (indx < 0)
return null;
int curindx = indx;
indx = getField(note, indx, "asset_id", false, out valuestr);
if (indx < 0)
get
{
indx = getField(note, curindx, "shadow_id", false, out valuestr);
if (indx < 0)
return null;
if (!UUID.TryParse(valuestr, out assetID))
return null;
assetID = deMoronize(assetID);
return lineNumber;
}
}
public NotecardReader(string _rawInput)
{
rawInput = (string)_rawInput.Clone();
lineNumber = 0;
}
public string getLine()
{
if(rawInput.Length == 0)
{
throw new NotANotecardFormatException(lineNumber + 1);
}
int pos = rawInput.IndexOf('\n');
if(pos < 0)
{
pos = rawInput.Length;
}
/* cut line from rest */
++lineNumber;
string line = rawInput.Substring(0, pos);
if (pos + 1 >= rawInput.Length)
{
rawInput = string.Empty;
}
else
{
if (!UUID.TryParse(valuestr, out assetID))
return null;
rawInput = rawInput.Substring(pos + 1);
}
ids.Add(assetID);
indx = note.IndexOf('}', indx); // skip to end of sale
if (indx < 0)
return null;
indx = getField(note, indx, "name", false, out valuestr); // avoid name contents
if (indx < 0)
return null;
indx = getField(note, indx, "desc", false, out valuestr); // avoid desc contents
if (indx < 0)
return null;
if(count > 1)
/* clean up line from double spaces and tabs */
line = line.Replace("\t", " ");
while(line.IndexOf(" ") >= 0)
{
indx = note.IndexOf("ext char index", indx); // skip to next
if (indx < 0)
return null;
line = line.Replace(" ", " ");
}
--count;
return line.Replace("\r", "").Trim();
}
indx = note.IndexOf("Text length",indx);
if(indx > 0)
public string getBlock(int length)
{
indx += 14;
List<UUID> textIDs = Util.GetUUIDsOnString(ref note, indx, note.Length - indx);
if(textIDs.Count > 0)
ids.AddRange(textIDs);
/* cut line from rest */
if(length > rawInput.Length)
{
throw new NotANotecardFormatException(lineNumber);
}
string line = rawInput.Substring(0, length);
rawInput = rawInput.Substring(length);
return line;
}
}
public class NotANotecardFormatException : Exception
{
public int lineNumber;
public NotANotecardFormatException(int _lineNumber)
: base()
{
lineNumber = _lineNumber;
}
}
private static void skipSection(NotecardReader reader)
{
if (reader.getLine() != "{")
throw new NotANotecardFormatException(reader.LineNumber);
string line;
while ((line = reader.getLine()) != "}")
{
if(line.IndexOf('{')>=0)
{
throw new NotANotecardFormatException(reader.LineNumber);
}
}
}
private static void skipInventoryItem(NotecardReader reader)
{
if (reader.getLine() != "{")
throw new NotANotecardFormatException(reader.LineNumber);
string line;
while((line = reader.getLine()) != "}")
{
string[] data = line.Split(' ');
if(data.Length == 0)
{
continue;
}
if(data[0] == "permissions")
{
skipSection(reader);
}
else if(data[0] == "sale_info")
{
skipSection(reader);
}
else if (line.IndexOf('{') >= 0)
{
throw new NotANotecardFormatException(reader.LineNumber);
}
}
}
private static void skipInventoryItems(NotecardReader reader)
{
if(reader.getLine() != "{")
{
throw new NotANotecardFormatException(reader.LineNumber);
}
string line;
while((line = reader.getLine()) != "}")
{
string[] data = line.Split(' ');
if(data.Length == 0)
{
continue;
}
if(data[0] == "inv_item")
{
skipInventoryItem(reader);
}
else if (line.IndexOf('{') >= 0)
{
throw new NotANotecardFormatException(reader.LineNumber);
}
}
}
private static void skipInventory(NotecardReader reader)
{
if (reader.getLine() != "{")
throw new NotANotecardFormatException(reader.LineNumber);
string line;
while((line = reader.getLine()) != "}")
{
string[] data = line.Split(' ');
if(data[0] == "count")
{
int count = Int32.Parse(data[1]);
for(int i = 0; i < count; ++i)
{
skipInventoryItems(reader);
}
}
else if (line.IndexOf('{') >= 0)
{
throw new NotANotecardFormatException(reader.LineNumber);
}
}
}
private static string readNotecardText(NotecardReader reader)
{
if (reader.getLine() != "{")
throw new NotANotecardFormatException(reader.LineNumber);
string notecardString = string.Empty;
string line;
while((line = reader.getLine()) != "}")
{
string[] data = line.Split(' ');
if (data.Length == 0)
{
continue;
}
if (data[0] == "LLEmbeddedItems")
{
skipInventory(reader);
}
else if(data[0] == "Text" && data.Length == 3)
{
int length = Int32.Parse(data[2]);
notecardString = reader.getBlock(length);
}
else if (line.IndexOf('{') >= 0)
{
throw new NotANotecardFormatException(reader.LineNumber);
}
}
return notecardString;
}
private static string readNotecard(byte[] rawInput)
{
string rawIntermedInput = string.Empty;
/* make up a Raw Encoding here */
foreach(byte c in rawInput)
{
char d = (char)c;
rawIntermedInput += d;
}
NotecardReader reader = new NotecardReader(rawIntermedInput);
string line;
try
{
line = reader.getLine();
}
catch(Exception)
{
return System.Text.Encoding.UTF8.GetString(rawInput);
}
string[] versioninfo = line.Split(' ');
if(versioninfo.Length < 3)
{
return System.Text.Encoding.UTF8.GetString(rawInput);
}
else if(versioninfo[0] != "Linden" || versioninfo[1] != "text")
{
return System.Text.Encoding.UTF8.GetString(rawInput);
}
else
{
/* now we actually decode the Encoding, before we needed it in raw */
string o = readNotecardText(reader);
byte[] a = new byte[o.Length];
for(int i = 0; i < o.Length; ++i)
{
a[i] = (byte)o[i];
}
return System.Text.Encoding.UTF8.GetString(a);
}
if (ids.Count == 0)
return null;
return ids;
}
/// <summary>
/// Parse a notecard in Linden format to a list of ordinary lines for LSL
/// Parse a notecard in Linden format to a string of ordinary text.
/// </summary>
/// <param name="rawInput"></param>
/// <returns></returns>
public static string[] ParseNotecardToArray(byte[] data)
public static string ParseNotecardToString(byte[] rawInput)
{
// check of a valid notecard
if (data == null || data.Length < 79)
return new string[0];
return readNotecard(rawInput);
}
//LSL can't read notecards with embedded items
if (data[58] != '0' || data[59] != '\n')
return new string[0];
string note = Util.UTF8.GetString(data);
if (String.IsNullOrWhiteSpace(note))
return new string[0];
// waste some time checking rigid versions
string tmpStr = note.Substring(0, 21);
if (!tmpStr.Equals("Linden text version 2"))
return new string[0];
tmpStr = note.Substring(24, 25);
if (!tmpStr.Equals("LLEmbeddedItems version 1"))
return new string[0];
tmpStr = note.Substring(52, 5);
if (!tmpStr.Equals("count"))
return new string[0];
int indx = note.IndexOf("Text length", 60);
if(indx < 0)
return new string[0];
indx += 12;
int end = indx + 1;
for (; end < note.Length && note[end] != '\n'; ++end);
if (note[end] != '\n')
return new string[0];
tmpStr = note.Substring(indx, end - indx);
if (!int.TryParse(tmpStr, out int textLen) || textLen == 0)
return new string[0];
indx = end + 1;
if (textLen + indx > data.Length)
return new string[0];
// yeackk
note = Util.UTF8.GetString(data, indx, textLen);
textLen = note.Length;
indx = 0;
var lines = new List<string>();
while (indx < textLen)
{
end = indx;
for (; end < textLen && note[end] != '\n'; ++end);
if(end == indx)
lines.Add(String.Empty);
else
lines.Add(note.Substring(indx, end - indx));
indx = end + 1;
}
// notes only seem to have one text section
if(lines.Count == 0)
return new string[0];
return lines.ToArray();
/// <summary>
/// Parse a notecard in Linden format to a list of ordinary lines.
/// </summary>
/// <param name="rawInput"></param>
/// <returns></returns>
public static string[] ParseNotecardToArray(byte[] rawInput)
{
return readNotecard(rawInput).Replace("\r", "").Split('\n');
}
}
}

View File

@ -125,8 +125,7 @@ namespace OpenSim.Framework.Serialization
ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV] = ASSET_EXTENSION_SEPARATOR + "sound.wav";
ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Texture] = ASSET_EXTENSION_SEPARATOR + "texture.jp2";
ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.TextureTGA] = ASSET_EXTENSION_SEPARATOR + "texture.tga";
ASSET_TYPE_TO_EXTENSION[(sbyte)OpenSimAssetType.Material] = ASSET_EXTENSION_SEPARATOR + "material.xml";
ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.Settings] = ASSET_EXTENSION_SEPARATOR + "settings.bin";
ASSET_TYPE_TO_EXTENSION[(sbyte)OpenSimAssetType.Material] = ASSET_EXTENSION_SEPARATOR + "material.xml"; // Not sure if we'll ever see this
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "animation.bvh"] = (sbyte)AssetType.Animation;
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "bodypart.txt"] = (sbyte)AssetType.Bodypart;
@ -148,7 +147,6 @@ namespace OpenSim.Framework.Serialization
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "texture.jp2"] = (sbyte)AssetType.Texture;
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "texture.tga"] = (sbyte)AssetType.TextureTGA;
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "material.xml"] = (sbyte)OpenSimAssetType.Material;
EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "settings.bin"] = (sbyte)AssetType.Settings;
}
public static string CreateOarLandDataPath(LandData ld)

View File

@ -400,7 +400,13 @@ namespace OpenSim.Framework.Serialization.External
/// <returns></returns>
public static string SanitizeXml(string xmlData)
{
return xmlData.Replace("xmlns:xmlns:", "xmlns:");
string fixedData = xmlData;
if (fixedData != null)
// Loop, because it may contain multiple
while (fixedData.Contains("xmlns:xmlns:"))
fixedData = fixedData.Replace("xmlns:xmlns:", "xmlns:");
return fixedData;
}
}
}

View File

@ -28,10 +28,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Framework.Serialization.External
{
@ -97,9 +99,6 @@ namespace OpenSim.Framework.Serialization.External
m_ldProcessors.Add(
"ParcelAccessList", ProcessParcelAccessList);
m_ldProcessors.Add(
"Environment", ProcessParcelEnvironment);
m_ldProcessors.Add(
"PassHours", (ld, xtr) => ld.PassHours = Convert.ToSingle(xtr.ReadElementString("PassHours")));
m_ldProcessors.Add(
@ -133,14 +132,6 @@ namespace OpenSim.Framework.Serialization.External
);
m_laeProcessors.Add(
"AccessList", (lae, xtr) => lae.Flags = (AccessList)Convert.ToUInt32(xtr.ReadElementString("AccessList")));
}
public static void ProcessParcelEnvironment(LandData ld, XmlReader xtr)
{
string senv = xtr.ReadElementString("Environment");
ld.Environment = ViewerEnvironment.FromOSDString(senv);
ld.EnvironmentVersion = ld.Environment.version;
}
public static void ProcessParcelAccessList(LandData ld, XmlReader xtr)
@ -264,15 +255,6 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("Dwell", "0");
xtw.WriteElementString("OtherCleanTime", Convert.ToString(landData.OtherCleanTime));
if(landData.Environment != null)
{
try
{
string senv = ViewerEnvironment.ToOSDString(landData.Environment);
xtw.WriteElementString("Environment", senv);
}
catch { }
}
xtw.WriteEndElement();
xtw.Close();

View File

@ -46,10 +46,9 @@ namespace OpenSim.Framework.Serialization.External
/// <param name="serializedSettings"></param>
/// <returns></returns>
/// <exception cref="System.Xml.XmlException"></exception>
public static RegionSettings Deserialize(byte[] serializedSettings, out ViewerEnvironment regionEnv)
public static RegionSettings Deserialize(byte[] serializedSettings)
{
// encoding is wrong. old oars seem to be on utf-16
return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length), out regionEnv);
return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length));
}
/// <summary>
@ -58,10 +57,9 @@ namespace OpenSim.Framework.Serialization.External
/// <param name="serializedSettings"></param>
/// <returns></returns>
/// <exception cref="System.Xml.XmlException"></exception>
public static RegionSettings Deserialize(string serializedSettings, out ViewerEnvironment regionEnv)
public static RegionSettings Deserialize(string serializedSettings)
{
RegionSettings settings = new RegionSettings();
regionEnv = null;
StringReader sr = new StringReader(serializedSettings);
XmlTextReader xtr = new XmlTextReader(sr);
@ -194,46 +192,21 @@ namespace OpenSim.Framework.Serialization.External
if (xtr.IsStartElement("Telehub"))
{
if (xtr.IsEmptyElement)
xtr.Read();
else
{
xtr.ReadStartElement("Telehub");
while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
{
switch (xtr.Name)
{
case "TelehubObject":
settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString());
break;
case "SpawnPoint":
string str = xtr.ReadElementContentAsString();
SpawnPoint sp = SpawnPoint.Parse(str);
settings.AddSpawnPoint(sp);
break;
}
}
xtr.ReadEndElement();
}
}
xtr.ReadStartElement("Telehub");
if (xtr.IsStartElement("Environment"))
{
if (xtr.IsEmptyElement)
xtr.Read();
else
while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
{
xtr.ReadStartElement("Environment");
while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
switch (xtr.Name)
{
switch (xtr.Name)
{
case "data":
regionEnv = ViewerEnvironment.FromOSDString(xtr.ReadElementContentAsString());
break;
}
case "TelehubObject":
settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString());
break;
case "SpawnPoint":
string str = xtr.ReadElementContentAsString();
SpawnPoint sp = SpawnPoint.Parse(str);
settings.AddSpawnPoint(sp);
break;
}
xtr.ReadEndElement();
}
}
@ -243,7 +216,7 @@ namespace OpenSim.Framework.Serialization.External
return settings;
}
public static string Serialize(RegionSettings settings, ViewerEnvironment RegionEnv)
public static string Serialize(RegionSettings settings)
{
StringWriter sw = new StringWriter();
XmlTextWriter xtw = new XmlTextWriter(sw);
@ -290,6 +263,8 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
// Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
// calculates it automatically according to the date and other factors.
xtw.WriteEndElement();
xtw.WriteStartElement("Telehub");
@ -301,13 +276,6 @@ namespace OpenSim.Framework.Serialization.External
}
xtw.WriteEndElement();
if (RegionEnv != null)
{
xtw.WriteStartElement("Environment");
xtw.WriteElementString("data", ViewerEnvironment.ToOSDString(RegionEnv));
xtw.WriteEndElement();
}
xtw.WriteEndElement();
xtw.Close();

View File

@ -130,7 +130,7 @@ namespace OpenSim.Framework.Serialization.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
RegionSettings deserRs = RegionSettingsSerializer.Deserialize(m_serializedRs, out ViewerEnvironment dummy);
RegionSettings deserRs = RegionSettingsSerializer.Deserialize(m_serializedRs);
Assert.That(deserRs, Is.Not.Null);
Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2));
Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics));

View File

@ -108,7 +108,7 @@ namespace OpenSim.Framework.Servers
return true;
return false;
}
}
/// <summary>
/// Must be overriden by child classes for their own server specific startup behaviour.
/// </summary>
@ -190,15 +190,8 @@ namespace OpenSim.Framework.Servers
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
m_log.InfoFormat(
"[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
Environment.OSVersion, Environment.OSVersion.Platform, Environment.Is64BitProcess ? "64" : "32");
Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
// next code can be changed on .net 4.7.x
if(Util.IsWindows())
m_log.InfoFormat("[STARTUP]: Processor Architecture: {0}({1})",
System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE", EnvironmentVariableTarget.Machine),
BitConverter.IsLittleEndian ?"le":"be");
// on other platforms we need to wait for .net4.7.1
try
{
StartupSpecific();

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,24 @@ namespace OpenSim.Framework.Servers.HttpServer
Description = description;
m_httpMethod = httpMethod;
m_path = path;
// FIXME: A very temporary measure to stop the simulator stats being overwhelmed with user CAPS info.
// Needs to be fixed properly in stats display
if (!path.StartsWith("/CAPS/"))
{
StatsManager.RegisterStat(
new Stat(
"requests",
"requests",
"Number of requests received by this service endpoint",
"requests",
"service",
string.Format("{0}:{1}", httpMethod, path),
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
s => s.Value = RequestsReceived,
StatVerbosity.Debug));
}
}
public virtual string Path

View File

@ -47,23 +47,30 @@ namespace OpenSim.Framework.Servers.HttpServer
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
byte[] data;
if (request is MemoryStream)
data = ((MemoryStream)request).ToArray();
else
{
request.Seek(0, SeekOrigin.Begin);
using (MemoryStream ms = new MemoryStream((int)request.Length))
{
request.CopyTo(ms);
data = ms.ToArray();
}
}
request.Dispose();
byte[] data = ReadFully(request);
string param = GetParam(path);
string responseString = m_method(data, path, param);
return Encoding.UTF8.GetBytes(responseString);
}
private static byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[1024];
using (MemoryStream ms = new MemoryStream(1024*256))
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
return ms.ToArray();
}
ms.Write(buffer, 0, read);
}
}
}
}
}

View File

@ -78,11 +78,7 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </returns>
bool AddHTTPHandler(string methodName, GenericHTTPMethod handler);
bool AddPollServiceHTTPHandler(string uripath, PollServiceEventArgs args);
bool AddPollServiceHTTPHandler(PollServiceEventArgs args);
void RemovePollServiceHTTPHandler(string url, string path);
void RemovePollServiceHTTPHandler(string path);
bool AddPollServiceHTTPHandler(string methodName, PollServiceEventArgs args);
/// <summary>
/// Adds a LLSD handler, yay.
@ -97,7 +93,6 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </summary>
/// <param name="handler"></param>
void AddStreamHandler(IRequestHandler handler);
void AddSimpleStreamHandler(ISimpleStreamHandler handler, bool varPath = false);
bool AddXmlRPCHandler(string method, XmlRpcMethod handler);
bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive);
@ -138,19 +133,18 @@ namespace OpenSim.Framework.Servers.HttpServer
/// <param name="path"></param>
void RemoveHTTPHandler(string httpMethod, string path);
void RemovePollServiceHTTPHandler(string httpMethod, string path);
bool RemoveLLSDHandler(string path, LLSDMethod handler);
void RemoveStreamHandler(string httpMethod, string path);
void RemoveSimpleStreamHandler(string path);
void RemoveXmlRPCHandler(string method);
void RemoveJsonRPCHandler(string method);
string GetHTTP404();
void AddIndexPHPMethodHandler(string key, SimpleStreamMethod sh);
void RemoveIndexPHPMethodHandler(string key);
SimpleStreamMethod TryGetIndexPHPMethodHandler(string key);
string GetHTTP404(string host);
string GetHTTP500();
}
}

View File

@ -27,7 +27,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
@ -52,14 +51,9 @@ namespace OpenSim.Framework.Servers.HttpServer
bool KeepAlive { get; }
NameValueCollection QueryString { get; }
Hashtable Query { get; }
HashSet<string> QueryFlags { get; }
Dictionary<string, string> QueryAsDictionary { get; } //faster than Query
string RawUrl { get; }
IPEndPoint RemoteIPEndPoint { get; }
IPEndPoint LocalIPEndPoint { get; }
Uri Url { get; }
string UriPath { get; }
string UserAgent { get; }
double ArrivalTS { get; }
}
}

View File

@ -92,16 +92,17 @@ namespace OpenSim.Framework.Servers.HttpServer
Stream OutputStream { get; }
string ProtocolVersion { get; set; }
int Priority { get; set; }
byte[] RawBuffer { get; set; }
int RawBufferStart { get; set; }
int RawBufferLen { get; set; }
/// <summary>
/// Return the output stream feeding the body.
/// </summary>
Stream Body { get; }
/// <summary>
/// Set a redirct location.
/// </summary>
string RedirectLocation { set; }
/// <summary>
/// Chunk transfers.
/// </summary>
@ -117,8 +118,6 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </summary>
string StatusDescription { get; set; }
double RequestTS { get; }
/// <summary>
/// Add a header field and content to the response.
/// </summary>

View File

@ -27,7 +27,6 @@
using System.Collections;
using System.IO;
using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Servers.HttpServer
{
@ -89,20 +88,4 @@ namespace OpenSim.Framework.Servers.HttpServer
{
Hashtable Handle(string path, Hashtable request);
}
public interface ISimpleStreamHandler
{
string Name { get; }
string Path { get; }
int RequestsReceived { get; }
int RequestsHandled { get; }
// Handle request stream, return byte array
void Handle(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
}
public delegate void SimpleStreamMethod(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
public delegate void SimpleOSDMapMethod(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap args);
public delegate void SimpleBinaryMethod(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, byte[] data);
}

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace OpenSim.Framework.Servers.HttpServer
{
/// <sumary>
/// Any OSHttpHandler must return one of the following results:
/// <list type = "table">
/// <listheader>
/// <term>result code</term>
/// <description>meaning</description>
/// </listheader>
/// <item>
/// <term>Pass</term>
/// <description>handler did not process the request</request>
/// </item>
/// <item>
/// <term>Done</term>
/// <description>handler did process the request, OSHttpServer
/// can clean up and close the request</request>
/// </item>
/// </list>
/// </summary>
public enum OSHttpHandlerResult
{
Unprocessed,
Pass,
Done,
}
/// <summary>
/// An OSHttpHandler that matches on the "content-type" header can
/// supply an OSHttpContentTypeChecker delegate which will be
/// invoked by the request matcher in OSHttpRequestPump.
/// </summary>
/// <returns>true if the handler is interested in the content;
/// false otherwise</returns>
public delegate bool OSHttpContentTypeChecker(OSHttpRequest req);
public abstract class OSHttpHandler
{
/// <summary>
/// Regular expression used to match against method of
/// the incoming HTTP request. If you want to match any string
/// either use '.*' or null. To match on the empty string use
/// '^$'.
/// </summary>
public virtual Regex Method
{
get { return _method; }
}
protected Regex _method;
/// <summary>
/// Regular expression used to match against path of the
/// incoming HTTP request. If you want to match any string
/// either use '.*' or null. To match on the empty string use
/// '^$'.
/// </summary>
public virtual Regex Path
{
get { return _path; }
}
protected Regex _path;
/// <summary>
/// Dictionary of (query name, regular expression) tuples,
/// allowing us to match on URI query fields.
/// </summary>
public virtual Dictionary<string, Regex> Query
{
get { return _query; }
}
protected Dictionary<string, Regex> _query;
/// <summary>
/// Dictionary of (header name, regular expression) tuples,
/// allowing us to match on HTTP header fields.
/// </summary>
public virtual Dictionary<string, Regex> Headers
{
get { return _headers; }
}
protected Dictionary<string, Regex> _headers;
/// <summary>
/// Dictionary of (header name, regular expression) tuples,
/// allowing us to match on HTTP header fields.
/// </summary>
/// <remarks>
/// This feature is currently not implemented as it requires
/// (trivial) changes to HttpServer.HttpListener that have not
/// been implemented.
/// </remarks>
public virtual Regex IPEndPointWhitelist
{
get { return _ipEndPointRegex; }
}
protected Regex _ipEndPointRegex;
/// <summary>
/// Base class constructor.
/// </summary>
/// <param name="path">null or path regex</param>
/// <param name="headers">null or dictionary of header
/// regexs</param>
/// <param name="contentType">null or content type
/// regex</param>
/// <param name="whitelist">null or IP address regex</param>
public OSHttpHandler(Regex method, Regex path, Dictionary<string, Regex> query,
Dictionary<string, Regex> headers, Regex contentType, Regex whitelist)
{
_method = method;
_path = path;
_query = query;
_ipEndPointRegex = whitelist;
if (null == _headers && null != contentType)
{
_headers = new Dictionary<string, Regex>();
_headers.Add("content-type", contentType);
}
}
/// <summary>
/// Process an incoming OSHttpRequest that matched our
/// requirements.
/// </summary>
/// <returns>
/// OSHttpHandlerResult.Pass if we are after all not
/// interested in the request; OSHttpHandlerResult.Done if we
/// did process the request.
/// </returns>
public abstract OSHttpHandlerResult Process(OSHttpRequest request);
public override string ToString()
{
StringWriter sw = new StringWriter();
sw.WriteLine("{0}", base.ToString());
sw.WriteLine(" method regex {0}", null == Method ? "null" : Method.ToString());
sw.WriteLine(" path regex {0}", null == Path ? "null": Path.ToString());
foreach (string tag in Headers.Keys)
{
sw.WriteLine(" header {0} : {1}", tag, Headers[tag].ToString());
}
sw.WriteLine(" IP whitelist {0}", null == IPEndPointWhitelist ? "null" : IPEndPointWhitelist.ToString());
sw.WriteLine();
sw.Close();
return sw.ToString();
}
}
}

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using log4net;
using Nwc.XmlRpc;
namespace OpenSim.Framework.Servers.HttpServer
{
public delegate XmlRpcResponse OSHttpHttpProcessor(XmlRpcRequest request);
public class OSHttpHttpHandler: OSHttpHandler
{
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// contains handler for processing HTTP Request
private GenericHTTPMethod _handler;
/// <summary>
/// Instantiate an HTTP handler.
/// </summary>
/// <param name="handler">a GenericHTTPMethod</param>
/// <param name="method">null or HTTP method regex</param>
/// <param name="path">null or path regex</param>
/// <param name="query">null or dictionary with query regexs</param>
/// <param name="headers">null or dictionary with header
/// regexs</param>
/// <param name="whitelist">null or IP address whitelist</param>
public OSHttpHttpHandler(GenericHTTPMethod handler, Regex method, Regex path,
Dictionary<string, Regex> query,
Dictionary<string, Regex> headers, Regex whitelist)
: base(method, path, query, headers, new Regex(@"^text/html", RegexOptions.IgnoreCase | RegexOptions.Compiled),
whitelist)
{
_handler = handler;
}
/// <summary>
/// Instantiate an HTTP handler.
/// </summary>
/// <param name="handler">a GenericHTTPMethod</param>
public OSHttpHttpHandler(GenericHTTPMethod handler)
: this(handler, new Regex(@"^GET$", RegexOptions.IgnoreCase | RegexOptions.Compiled), null, null, null, null)
{
}
/// <summary>
/// Invoked by OSHttpRequestPump.
/// </summary>
public override OSHttpHandlerResult Process(OSHttpRequest request)
{
// call handler method
Hashtable responseData = _handler(request.Query);
int responseCode = (int)responseData["int_response_code"];
string responseString = (string)responseData["str_response_string"];
string contentType = (string)responseData["content_type"];
//Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
//and should check for NullReferenceExceptions
if (string.IsNullOrEmpty(contentType))
{
contentType = "text/html";
}
OSHttpResponse response = new OSHttpResponse(request);
// We're forgoing the usual error status codes here because the client
// ignores anything but 200 and 301
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
if (responseCode == (int)OSHttpStatusCode.RedirectMovedPermanently)
{
response.RedirectLocation = (string)responseData["str_redirect_location"];
response.StatusCode = responseCode;
}
response.AddHeader("Content-type", contentType);
byte[] buffer;
if (!contentType.Contains("image"))
{
buffer = Encoding.UTF8.GetBytes(responseString);
}
else
{
buffer = Convert.FromBase64String(responseString);
}
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
try
{
response.Body.Write(buffer, 0, buffer.Length);
}
catch (Exception ex)
{
_log.ErrorFormat("[OSHttpHttpHandler]: Error: {0}", ex.Message);
}
finally
{
response.Send();
}
return OSHttpHandlerResult.Done;
}
}
}

View File

@ -34,7 +34,7 @@ using System.Net;
using System.Reflection;
using System.Text;
using System.Web;
using OSHttpServer;
using HttpServer;
using log4net;
namespace OpenSim.Framework.Servers.HttpServer
@ -43,23 +43,23 @@ namespace OpenSim.Framework.Servers.HttpServer
{
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected IHttpRequest m_request = null;
protected IHttpClientContext m_context = null;
protected IHttpRequest _request = null;
protected IHttpClientContext _context = null;
public string[] AcceptTypes
{
get { return m_request.AcceptTypes; }
get { return _request.AcceptTypes; }
}
public Encoding ContentEncoding
{
get { return m_contentEncoding; }
get { return _contentEncoding; }
}
private Encoding m_contentEncoding;
private Encoding _contentEncoding;
public long ContentLength
{
get { return m_request.ContentLength; }
get { return _request.ContentLength; }
}
public long ContentLength64
@ -69,142 +69,99 @@ namespace OpenSim.Framework.Servers.HttpServer
public string ContentType
{
get { return m_contentType; }
get { return _contentType; }
}
private string m_contentType;
private string _contentType;
public HttpCookieCollection Cookies
{
get
{
RequestCookies cookies = m_request.Cookies;
RequestCookies cookies = _request.Cookies;
HttpCookieCollection httpCookies = new HttpCookieCollection();
if(cookies != null)
{
foreach (RequestCookie cookie in cookies)
httpCookies.Add(new HttpCookie(cookie.Name, cookie.Value));
}
foreach (RequestCookie cookie in cookies)
httpCookies.Add(new HttpCookie(cookie.Name, cookie.Value));
return httpCookies;
}
}
public bool HasEntityBody
{
get { return m_request.ContentLength != 0; }
get { return _request.ContentLength != 0; }
}
public NameValueCollection Headers
{
get { return m_request.Headers; }
get { return _request.Headers; }
}
public string HttpMethod
{
get { return m_request.Method; }
get { return _request.Method; }
}
public Stream InputStream
{
get { return m_request.Body; }
get { return _request.Body; }
}
public bool IsSecured
{
get { return m_context.IsSecured; }
get { return _context.IsSecured; }
}
public bool KeepAlive
{
get { return ConnectionType.KeepAlive == m_request.Connection; }
get { return ConnectionType.KeepAlive == _request.Connection; }
}
public NameValueCollection QueryString
{
get { return m_request.QueryString;}
get { return _queryString; }
}
private NameValueCollection _queryString;
private Hashtable m_queryAsHashtable = null;
public Hashtable Query
{
get
{
if (m_queryAsHashtable == null)
BuildQueryHashtable();
return m_queryAsHashtable;
}
get { return _query; }
}
private Hashtable _query;
//faster than Query
private Dictionary<string, string> _queryAsDictionay = null;
public Dictionary<string,string> QueryAsDictionary
{
get
{
if (_queryAsDictionay == null)
BuildQueryDictionary();
return _queryAsDictionay;
}
}
private HashSet<string> m_queryFlags = null;
public HashSet<string> QueryFlags
{
get
{
if (m_queryFlags == null)
BuildQueryDictionary();
return m_queryFlags;
}
}
/// <value>
/// POST request values, if applicable
/// </value>
// public Hashtable Form { get; private set; }
/// <value>
/// POST request values, if applicable
/// </value>
// public Hashtable Form { get; private set; }
public string RawUrl
{
get { return m_request.Uri.AbsolutePath; }
get { return _request.Uri.AbsolutePath; }
}
public IPEndPoint RemoteIPEndPoint
{
get { return m_request.RemoteIPEndPoint; }
}
public IPEndPoint LocalIPEndPoint
{
get { return m_request.LocalIPEndPoint; }
get { return _remoteIPEndPoint; }
}
private IPEndPoint _remoteIPEndPoint;
public Uri Url
{
get { return m_request.Uri; }
}
public string UriPath
{
get { return m_request.UriPath; }
get { return _request.Uri; }
}
public string UserAgent
{
get { return m_userAgent; }
}
private string m_userAgent;
public double ArrivalTS
{
get { return m_request.ArrivalTS;}
get { return _userAgent; }
}
private string _userAgent;
internal IHttpRequest IHttpRequest
{
get { return m_request; }
get { return _request; }
}
internal IHttpClientContext IHttpClientContext
{
get { return m_context; }
get { return _context; }
}
/// <summary>
@ -219,27 +176,73 @@ namespace OpenSim.Framework.Servers.HttpServer
public OSHttpRequest() {}
public OSHttpRequest(IHttpRequest req)
public OSHttpRequest(IHttpClientContext context, IHttpRequest req)
{
m_request = req;
m_context = req.Context;
_request = req;
_context = context;
if (null != req.Headers["content-encoding"])
{
try
{
m_contentEncoding = Encoding.GetEncoding(m_request.Headers["content-encoding"]);
_contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
}
catch
catch (Exception)
{
// ignore
}
}
if (null != req.Headers["content-type"])
m_contentType = m_request.Headers["content-type"];
_contentType = _request.Headers["content-type"];
if (null != req.Headers["user-agent"])
m_userAgent = req.Headers["user-agent"];
_userAgent = req.Headers["user-agent"];
if (null != req.Headers["remote_addr"])
{
try
{
IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]);
// sometimes req.Headers["remote_port"] returns a comma separated list, so use
// the first one in the list and log it
string[] strPorts = req.Headers["remote_port"].Split(new char[] { ',' });
if (strPorts.Length > 1)
{
_log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
req.Headers["remote_addr"], req.Headers["remote_port"]);
}
int port = Int32.Parse(strPorts[0]);
_remoteIPEndPoint = new IPEndPoint(addr, port);
}
catch (FormatException)
{
_log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
req.Headers["remote_addr"], req.Headers["remote_port"]);
}
}
_queryString = new NameValueCollection();
_query = new Hashtable();
try
{
foreach (HttpInputItem item in req.QueryString)
{
try
{
_queryString.Add(item.Name, item.Value);
_query[item.Name] = item.Value;
}
catch (InvalidCastException)
{
_log.DebugFormat("[OSHttpRequest]: error parsing {0} query item, skipping it", item.Name);
continue;
}
}
}
catch (Exception)
{
_log.ErrorFormat("[OSHttpRequest]: Error parsing querystring");
}
// Form = new Hashtable();
// foreach (HttpInputItem item in req.Form)
@ -249,44 +252,6 @@ namespace OpenSim.Framework.Servers.HttpServer
// }
}
private void BuildQueryDictionary()
{
NameValueCollection q = m_request.QueryString;
_queryAsDictionay = new Dictionary<string, string>();
m_queryFlags = new HashSet<string>();
for(int i = 0; i <q.Count; ++i)
{
try
{
var name = q.GetKey(i);
if(!string.IsNullOrEmpty(name))
_queryAsDictionay[name] = q[i];
else
m_queryFlags.Add(q[i]);
}
catch {}
}
}
private void BuildQueryHashtable()
{
NameValueCollection q = m_request.QueryString;
m_queryAsHashtable = new Hashtable();
m_queryFlags = new HashSet<string>();
for (int i = 0; i < q.Count; ++i)
{
try
{
var name = q.GetKey(i);
if (!string.IsNullOrEmpty(name))
m_queryAsHashtable[name] = q[i];
else
m_queryFlags.Add(q[i]);
}
catch { }
}
}
public override string ToString()
{
StringBuilder me = new StringBuilder();

View File

@ -0,0 +1,298 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// #define DEBUGGING
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using log4net;
using HttpServer;
namespace OpenSim.Framework.Servers.HttpServer
{
/// <summary>
/// An OSHttpRequestPump fetches incoming OSHttpRequest objects
/// from the OSHttpRequestQueue and feeds them to all subscribed
/// parties. Each OSHttpRequestPump encapsulates one thread to do
/// the work and there is a fixed number of pumps for each
/// OSHttpServer object.
/// </summary>
public class OSHttpRequestPump
{
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected OSHttpServer _server;
protected OSHttpRequestQueue _queue;
protected Thread _engine;
private int _id;
public string EngineID
{
get { return String.Format("{0} pump {1}", _server.EngineID, _id); }
}
public OSHttpRequestPump(OSHttpServer server, OSHttpRequestQueue queue, int id)
{
_server = server;
_queue = queue;
_id = id;
_engine = new Thread(new ThreadStart(Engine));
_engine.IsBackground = true;
_engine.Start();
_engine.Name = string.Format ("Engine:{0}",EngineID);
ThreadTracker.Add(_engine);
}
public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize)
{
OSHttpRequestPump[] pumps = new OSHttpRequestPump[poolSize];
for (int i = 0; i < pumps.Length; i++)
{
pumps[i] = new OSHttpRequestPump(server, queue, i);
}
return pumps;
}
public void Start()
{
_engine = new Thread(new ThreadStart(Engine));
_engine.IsBackground = true;
_engine.Start();
_engine.Name = string.Format ("Engine:{0}",EngineID);
ThreadTracker.Add(_engine);
}
public void Engine()
{
OSHttpRequest req = null;
while (true)
{
try
{
// dequeue an OSHttpRequest from OSHttpServer's
// request queue
req = _queue.Dequeue();
// get a copy of the list of registered handlers
List<OSHttpHandler> handlers = _server.OSHttpHandlers;
// prune list and have it sorted from most
// specific to least specific
handlers = MatchHandlers(req, handlers);
// process req: we try each handler in turn until
// we are either out of handlers or get back a
// Pass or Done
OSHttpHandlerResult rc = OSHttpHandlerResult.Unprocessed;
foreach (OSHttpHandler h in handlers)
{
rc = h.Process(req);
// Pass: handler did not process the request,
// try next handler
if (OSHttpHandlerResult.Pass == rc) continue;
// Handled: handler has processed the request
if (OSHttpHandlerResult.Done == rc) break;
// hmm, something went wrong
throw new Exception(String.Format("[{0}] got unexpected OSHttpHandlerResult {1}", EngineID, rc));
}
if (OSHttpHandlerResult.Unprocessed == rc)
{
_log.InfoFormat("[{0}] OSHttpHandler: no handler registered for {1}", EngineID, req);
// set up response header
OSHttpResponse resp = new OSHttpResponse(req);
resp.StatusCode = (int)OSHttpStatusCode.ClientErrorNotFound;
resp.StatusDescription = String.Format("no handler on call for {0}", req);
resp.ContentType = "text/html";
// add explanatory message
StreamWriter body = new StreamWriter(resp.Body);
body.WriteLine("<html>");
body.WriteLine("<header><title>Ooops...</title><header>");
body.WriteLine(String.Format("<body><p>{0}</p></body>", resp.StatusDescription));
body.WriteLine("</html>");
body.Flush();
// and ship it back
resp.Send();
}
}
catch (Exception e)
{
_log.DebugFormat("[{0}] OSHttpHandler problem: {1}", EngineID, e.ToString());
_log.ErrorFormat("[{0}] OSHttpHandler problem: {1}", EngineID, e.Message);
}
}
}
protected List<OSHttpHandler> MatchHandlers(OSHttpRequest req, List<OSHttpHandler> handlers)
{
Dictionary<OSHttpHandler, int> scoredHandlers = new Dictionary<OSHttpHandler, int>();
_log.DebugFormat("[{0}] MatchHandlers for {1}", EngineID, req);
foreach (OSHttpHandler h in handlers)
{
// initial anchor
scoredHandlers[h] = 0;
// first, check whether IPEndPointWhitelist applies
// and, if it does, whether client is on that white
// list.
if (null != h.IPEndPointWhitelist)
{
// TODO: following code requires code changes to
// HttpServer.HttpRequest to become functional
IPEndPoint remote = req.RemoteIPEndPoint;
if (null != remote)
{
Match epm = h.IPEndPointWhitelist.Match(remote.ToString());
if (!epm.Success)
{
scoredHandlers.Remove(h);
continue;
}
}
}
if (null != h.Method)
{
Match m = h.Method.Match(req.HttpMethod);
if (!m.Success)
{
scoredHandlers.Remove(h);
continue;
}
scoredHandlers[h]++;
}
// whitelist ok, now check path
if (null != h.Path)
{
Match m = h.Path.Match(req.RawUrl);
if (!m.Success)
{
scoredHandlers.Remove(h);
continue;
}
scoredHandlers[h] += m.ToString().Length;
}
// whitelist & path ok, now check query string
if (null != h.Query)
{
int queriesMatch = MatchOnNameValueCollection(req.QueryString, h.Query);
if (0 == queriesMatch)
{
_log.DebugFormat("[{0}] request {1}", EngineID, req);
_log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
scoredHandlers.Remove(h);
continue;
}
scoredHandlers[h] += queriesMatch;
}
// whitelist, path, query string ok, now check headers
if (null != h.Headers)
{
int headersMatch = MatchOnNameValueCollection(req.Headers, h.Headers);
if (0 == headersMatch)
{
_log.DebugFormat("[{0}] request {1}", EngineID, req);
_log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
scoredHandlers.Remove(h);
continue;
}
scoredHandlers[h] += headersMatch;
}
}
List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys);
matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y)
{
return scoredHandlers[x] - scoredHandlers[y];
});
LogDumpHandlerList(matchingHandlers);
return matchingHandlers;
}
protected int MatchOnNameValueCollection(NameValueCollection collection, Dictionary<string, Regex> regexs)
{
int matched = 0;
foreach (string tag in regexs.Keys)
{
// do we have a header "tag"?
if (null == collection[tag])
{
return 0;
}
// does the content of collection[tag] match
// the supplied regex?
Match cm = regexs[tag].Match(collection[tag]);
if (!cm.Success)
{
return 0;
}
// ok: matches
matched++;
continue;
}
return matched;
}
[ConditionalAttribute("DEBUGGING")]
private void LogDumpHandlerList(List<OSHttpHandler> l)
{
_log.DebugFormat("[{0}] OSHttpHandlerList dump:", EngineID);
foreach (OSHttpHandler h in l)
_log.DebugFormat(" ", h.ToString());
}
}
}

View File

@ -26,58 +26,43 @@
*/
using System;
using System.Collections.Generic;
using System.Threading;
using HttpServer;
namespace OpenSim.Framework.Servers.HttpServer
{
/// <summary>
/// simple Base streamed request handler
/// for well defined simple uri paths, any http method
/// OSHttpRequestQueues are used to hand over incoming HTTP
/// requests to OSHttpRequestPump objects.
/// </summary>
public abstract class SimpleBaseRequestHandler
public class OSHttpRequestQueue : Queue<OSHttpRequest>
{
public int RequestsReceived { get; protected set; }
private object _syncObject = new object();
public int RequestsHandled { get; protected set; }
private readonly string m_path;
public string Name { get; private set; }
protected SimpleBaseRequestHandler(string path)
new public void Enqueue(OSHttpRequest req)
{
Name = null;
m_path = path;
}
protected SimpleBaseRequestHandler(string path, string name)
{
Name = name;
m_path = path;
}
public string Path
{
get { return m_path; }
}
public string GetParam(string path)
{
if (CheckParam(path))
lock (_syncObject)
{
return path.Substring(m_path.Length);
base.Enqueue(req);
Monitor.Pulse(_syncObject);
}
}
new public OSHttpRequest Dequeue()
{
OSHttpRequest req = null;
lock (_syncObject)
{
while (null == req)
{
Monitor.Wait(_syncObject);
if (0 != this.Count) req = base.Dequeue();
}
}
return string.Empty;
}
protected bool CheckParam(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
return path.StartsWith(Path);
return req;
}
}
}
}

View File

@ -28,7 +28,7 @@
using System.IO;
using System.Net;
using System.Text;
using OSHttpServer;
using HttpServer;
namespace OpenSim.Framework.Servers.HttpServer
{
@ -231,18 +231,19 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
public int Priority
/// <summary>
/// Set a redirct location.
/// </summary>
public string RedirectLocation
{
get
{
return _httpResponse.Priority;
}
// get { return _redirectLocation; }
set
{
_httpResponse.Priority = value;
_httpResponse.Redirect(value);
}
}
/// <summary>
/// Chunk transfers.
/// </summary>
@ -275,10 +276,6 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
public double RequestTS
{
get {return _httpResponse.RequestTS; }
}
/// <summary>
/// HTTP status description.
@ -313,7 +310,8 @@ namespace OpenSim.Framework.Servers.HttpServer
/// replying</param>
public OSHttpResponse(OSHttpRequest req)
{
_httpResponse = new HttpResponse(req.IHttpRequest);
_httpResponse = new HttpResponse(req.IHttpClientContext, req.IHttpRequest);
}
public OSHttpResponse(HttpResponse resp)

View File

@ -0,0 +1,210 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using System.Security.Cryptography.X509Certificates;
using log4net;
using HttpServer;
using HttpListener = HttpServer.HttpListener;
namespace OpenSim.Framework.Servers.HttpServer
{
/// <summary>
/// OSHttpServer provides an HTTP server bound to a specific
/// port. When instantiated with just address and port it uses
/// normal HTTP, when instantiated with address, port, and X509
/// certificate, it uses HTTPS.
/// </summary>
public class OSHttpServer
{
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private object _syncObject = new object();
// underlying HttpServer.HttpListener
protected HttpListener _listener;
// underlying core/engine thread
protected Thread _engine;
// Queue containing (OS)HttpRequests
protected OSHttpRequestQueue _queue;
// OSHttpRequestPumps "pumping" incoming OSHttpRequests
// upwards
protected OSHttpRequestPump[] _pumps;
// thread identifier
protected string _engineId;
public string EngineID
{
get { return _engineId; }
}
/// <summary>
/// True if this is an HTTPS connection; false otherwise.
/// </summary>
protected bool _isSecure;
public bool IsSecure
{
get { return _isSecure; }
}
public int QueueSize
{
get { return _pumps.Length; }
}
/// <summary>
/// List of registered OSHttpHandlers for this OSHttpServer instance.
/// </summary>
protected List<OSHttpHandler> _httpHandlers = new List<OSHttpHandler>();
public List<OSHttpHandler> OSHttpHandlers
{
get
{
lock (_httpHandlers)
{
return new List<OSHttpHandler>(_httpHandlers);
}
}
}
/// <summary>
/// Instantiate an HTTP server.
/// </summary>
public OSHttpServer(IPAddress address, int port, int poolSize)
{
_engineId = String.Format("OSHttpServer (HTTP:{0})", port);
_isSecure = false;
_log.DebugFormat("[{0}] HTTP server instantiated", EngineID);
_listener = new HttpListener(address, port);
_queue = new OSHttpRequestQueue();
_pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize);
}
/// <summary>
/// Instantiate an HTTPS server.
/// </summary>
public OSHttpServer(IPAddress address, int port, X509Certificate certificate, int poolSize)
{
_engineId = String.Format("OSHttpServer [HTTPS:{0}/ps:{1}]", port, poolSize);
_isSecure = true;
_log.DebugFormat("[{0}] HTTPS server instantiated", EngineID);
_listener = new HttpListener(address, port, certificate);
_queue = new OSHttpRequestQueue();
_pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize);
}
/// <summary>
/// Turn an HttpRequest into an OSHttpRequestItem and place it
/// in the queue. The OSHttpRequestQueue object will pulse the
/// next available idle pump.
/// </summary>
protected void OnHttpRequest(HttpClientContext client, HttpRequest request)
{
// turn request into OSHttpRequest
OSHttpRequest req = new OSHttpRequest(client, request);
// place OSHttpRequest into _httpRequestQueue, will
// trigger Pulse to idle waiting pumps
_queue.Enqueue(req);
}
/// <summary>
/// Start the HTTP server engine.
/// </summary>
public void Start()
{
_engine = new Thread(new ThreadStart(Engine));
_engine.IsBackground = true;
_engine.Start();
_engine.Name = string.Format ("Engine:{0}",_engineId);
ThreadTracker.Add(_engine);
// start the pumps...
for (int i = 0; i < _pumps.Length; i++)
_pumps[i].Start();
}
public void Stop()
{
lock (_syncObject) Monitor.Pulse(_syncObject);
}
/// <summary>
/// Engine keeps the HTTP server running.
/// </summary>
private void Engine()
{
try {
_listener.RequestHandler += OnHttpRequest;
_listener.Start(QueueSize);
_log.InfoFormat("[{0}] HTTP server started", EngineID);
lock (_syncObject) Monitor.Wait(_syncObject);
}
catch (Exception ex)
{
_log.DebugFormat("[{0}] HTTP server startup failed: {1}", EngineID, ex.ToString());
}
_log.InfoFormat("[{0}] HTTP server terminated", EngineID);
}
/// <summary>
/// Add an HTTP request handler.
/// </summary>
/// <param name="handler">OSHttpHandler delegate</param>
/// <param name="path">regex object for path matching</parm>
/// <param name="headers">dictionary containing header names
/// and regular expressions to match against header values</param>
public void AddHandler(OSHttpHandler handler)
{
lock (_httpHandlers)
{
if (_httpHandlers.Contains(handler))
{
_log.DebugFormat("[OSHttpServer] attempt to add already existing handler ignored");
return;
}
_httpHandlers.Add(handler);
}
}
}
}

View File

@ -1,33 +0,0 @@
using System;
using System.Net;
namespace OSHttpServer.Exceptions
{
/// <summary>
/// The request could not be understood by the server due to malformed syntax.
/// The client SHOULD NOT repeat the request without modifications.
///
/// Text taken from: http://www.submissionchamber.com/help-guides/error-codes.php
/// </summary>
public class BadRequestException : HttpException
{
/// <summary>
/// Create a new bad request exception.
/// </summary>
/// <param name="errMsg">reason to why the request was bad.</param>
public BadRequestException(string errMsg)
: base(HttpStatusCode.BadRequest, errMsg)
{
}
/// <summary>
/// Create a new bad request exception.
/// </summary>
/// <param name="errMsg">reason to why the request was bad.</param>
/// <param name="inner">inner exception</param>
public BadRequestException(string errMsg, Exception inner)
: base(HttpStatusCode.BadRequest, errMsg, inner)
{
}
}
}

View File

@ -1,55 +0,0 @@
using System;
namespace OSHttpServer.Parser
{
/// <summary>
/// Arguments used when more body bytes have come.
/// </summary>
public class BodyEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="BodyEventArgs"/> class.
/// </summary>
/// <param name="buffer">buffer that contains the received bytes.</param>
/// <param name="offset">offset in buffer where to start processing.</param>
/// <param name="count">number of bytes from <paramref name="offset"/> that should be parsed.</param>
public BodyEventArgs(byte[] buffer, int offset, int count)
{
Buffer = buffer;
Offset = offset;
Count = count;
}
/// <summary>
/// Initializes a new instance of the <see cref="BodyEventArgs"/> class.
/// </summary>
public BodyEventArgs()
{
}
/// <summary>
/// Gets or sets buffer that contains the received bytes.
/// </summary>
public byte[] Buffer { get; set; }
/*
/// <summary>
/// Gets or sets number of bytes used by the request.
/// </summary>
public int BytesUsed { get; set; }
*/
/// <summary>
/// Gets or sets number of bytes from <see cref="Offset"/> that should be parsed.
/// </summary>
public int Count { get; set; }
/*
/// <summary>
/// Gets or sets whether the body is complete.
/// </summary>
public bool IsBodyComplete { get; set; }
*/
/// <summary>
/// Gets or sets offset in buffer where to start processing.
/// </summary>
public int Offset { get; set; }
}
}

View File

@ -1,50 +0,0 @@
using System;
using System.Net.Sockets;
namespace OSHttpServer
{
/// <summary>
/// Invoked when a client have been accepted by the <see cref="OSHttpListener"/>
/// </summary>
/// <remarks>
/// Can be used to revoke incoming connections
/// </remarks>
public class ClientAcceptedEventArgs : EventArgs
{
private readonly Socket _socket;
private bool _revoke;
/// <summary>
/// Initializes a new instance of the <see cref="ClientAcceptedEventArgs"/> class.
/// </summary>
/// <param name="socket">The socket.</param>
public ClientAcceptedEventArgs(Socket socket)
{
_socket = socket;
}
/// <summary>
/// Accepted socket.
/// </summary>
public Socket Socket
{
get { return _socket; }
}
/// <summary>
/// Client should be revoked.
/// </summary>
public bool Revoked
{
get { return _revoke; }
}
/// <summary>
/// Client may not be handled.
/// </summary>
public void Revoke()
{
_revoke = true;
}
}
}

View File

@ -1,414 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Globalization;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace OSHttpServer
{
/// <summary>
/// Timeout Manager. Checks for dead clients. Clients with open connections that are not doing anything. Closes sessions opened with keepalive.
/// </summary>
public static class ContextTimeoutManager
{
/// <summary>
/// Use a Thread or a Timer to monitor the ugly
/// </summary>
private static Thread m_internalThread = null;
private static object m_threadLock = new object();
private static ConcurrentQueue<HttpClientContext> m_contexts = new ConcurrentQueue<HttpClientContext>();
private static ConcurrentQueue<HttpClientContext> m_highPrio = new ConcurrentQueue<HttpClientContext>();
private static ConcurrentQueue<HttpClientContext> m_midPrio = new ConcurrentQueue<HttpClientContext>();
private static ConcurrentQueue<HttpClientContext> m_lowPrio = new ConcurrentQueue<HttpClientContext>();
private static AutoResetEvent m_processWaitEven = new AutoResetEvent(false);
private static bool m_shuttingDown;
private static int m_ActiveSendingCount;
private static double m_lastTimeOutCheckTime = 0;
private static double m_lastSendCheckTime = 0;
const int m_maxBandWidth = 10485760; //80Mbps
const int m_maxConcurrenSend = 32;
static ContextTimeoutManager()
{
TimeStampClockPeriod = 1.0 / (double)Stopwatch.Frequency;
TimeStampClockPeriodMS = 1e3 / (double)Stopwatch.Frequency;
}
public static void Start()
{
lock (m_threadLock)
{
if (m_internalThread != null)
return;
m_lastTimeOutCheckTime = GetTimeStampMS();
m_internalThread = new Thread(ThreadRunProcess);
m_internalThread.Priority = ThreadPriority.Normal;
m_internalThread.IsBackground = true;
m_internalThread.CurrentCulture = new CultureInfo("en-US", false);
m_internalThread.Name = "HttpServerMain";
m_internalThread.Start();
}
}
public static void Stop()
{
m_shuttingDown = true;
m_internalThread.Join();
ProcessShutDown();
}
private static void ThreadRunProcess()
{
while (!m_shuttingDown)
{
m_processWaitEven.WaitOne(500);
if(m_shuttingDown)
return;
double now = GetTimeStamp();
if(m_contexts.Count > 0)
{
ProcessSendQueues(now);
if (now - m_lastTimeOutCheckTime > 1.0)
{
ProcessContextTimeouts();
m_lastTimeOutCheckTime = now;
}
}
else
m_lastTimeOutCheckTime = now;
}
}
public static void ProcessShutDown()
{
try
{
SocketError disconnectError = SocketError.HostDown;
for (int i = 0; i < m_contexts.Count; i++)
{
if (m_contexts.TryDequeue(out HttpClientContext context))
{
try
{
context.Disconnect(disconnectError);
}
catch { }
}
}
m_processWaitEven.Dispose();
m_processWaitEven = null;
}
catch
{
// We can't let this crash.
}
}
public static void ProcessSendQueues(double now)
{
int inqueues = m_highPrio.Count + m_midPrio.Count + m_lowPrio.Count;
if(inqueues == 0)
return;
double dt = now - m_lastSendCheckTime;
m_lastSendCheckTime = now;
int totalSending = m_ActiveSendingCount;
int curConcurrentLimit = m_maxConcurrenSend - totalSending;
if(curConcurrentLimit <= 0)
return;
if(curConcurrentLimit > inqueues)
curConcurrentLimit = inqueues;
if (dt > 0.5)
dt = 0.5;
dt /= curConcurrentLimit;
int curbytesLimit = (int)(m_maxBandWidth * dt);
if(curbytesLimit < 8192)
curbytesLimit = 8192;
HttpClientContext ctx;
int sent;
while (curConcurrentLimit > 0)
{
sent = 0;
while (m_highPrio.TryDequeue(out ctx))
{
if(TrySend(ctx, curbytesLimit))
m_highPrio.Enqueue(ctx);
if (m_shuttingDown)
return;
--curConcurrentLimit;
if (++sent == 4)
break;
}
sent = 0;
while(m_midPrio.TryDequeue(out ctx))
{
if(TrySend(ctx, curbytesLimit))
m_midPrio.Enqueue(ctx);
if (m_shuttingDown)
return;
--curConcurrentLimit;
if (++sent >= 2)
break;
}
if (m_lowPrio.TryDequeue(out ctx))
{
--curConcurrentLimit;
if(TrySend(ctx, curbytesLimit))
m_lowPrio.Enqueue(ctx);
}
if (m_shuttingDown)
return;
}
}
private static bool TrySend(HttpClientContext ctx, int bytesLimit)
{
if(!ctx.CanSend())
return false;
return ctx.TrySendResponse(bytesLimit);
}
/// <summary>
/// Causes the watcher to immediately check the connections.
/// </summary>
public static void ProcessContextTimeouts()
{
try
{
for (int i = 0; i < m_contexts.Count; i++)
{
if (m_shuttingDown)
return;
if (m_contexts.TryDequeue(out HttpClientContext context))
{
if (!ContextTimedOut(context, out SocketError disconnectError))
m_contexts.Enqueue(context);
else if(disconnectError != SocketError.InProgress)
context.Disconnect(disconnectError);
}
}
}
catch
{
// We can't let this crash.
}
}
private static bool ContextTimedOut(HttpClientContext context, out SocketError disconnectError)
{
disconnectError = SocketError.InProgress;
// First our error conditions
if (context.contextID < 0 || context.StopMonitoring || context.StreamPassedOff)
return true;
int nowMS = EnvironmentTickCount();
// First we check first contact line
if (!context.FirstRequestLineReceived)
{
if (EnvironmentTickCountAdd(context.TimeoutFirstLine, context.LastActivityTimeMS) < nowMS)
{
disconnectError = SocketError.TimedOut;
return true;
}
return false;
}
// First we check first contact request
if (!context.FullRequestReceived)
{
if (EnvironmentTickCountAdd(context.TimeoutRequestReceived, context.LastActivityTimeMS) < nowMS)
{
disconnectError = SocketError.TimedOut;
return true;
}
return false;
}
if (context.TriggerKeepalive)
{
context.TriggerKeepalive = false;
context.MonitorKeepaliveStartMS = nowMS + 500;
return false;
}
if (context.MonitorKeepaliveStartMS != 0)
{
if (context.IsClosing)
{
disconnectError = SocketError.Success;
return true;
}
if (EnvironmentTickCountAdd(context.TimeoutKeepAlive, context.MonitorKeepaliveStartMS) < nowMS)
{
disconnectError = SocketError.TimedOut;
context.MonitorKeepaliveStartMS = 0;
return true;
}
}
if (EnvironmentTickCountAdd(context.TimeoutMaxIdle, context.LastActivityTimeMS) < nowMS)
{
disconnectError = SocketError.TimedOut;
context.MonitorKeepaliveStartMS = 0;
return true;
}
return false;
}
public static void StartMonitoringContext(HttpClientContext context)
{
context.LastActivityTimeMS = EnvironmentTickCount();
m_contexts.Enqueue(context);
}
public static void EnqueueSend(HttpClientContext context, int priority, bool notThrottled = true)
{
switch(priority)
{
case 0:
m_highPrio.Enqueue(context);
break;
case 1:
m_midPrio.Enqueue(context);
break;
case 2:
m_lowPrio.Enqueue(context);
break;
default:
return;
}
if(notThrottled)
m_processWaitEven.Set();
}
public static void ContextEnterActiveSend()
{
Interlocked.Increment(ref m_ActiveSendingCount);
}
public static void ContextLeaveActiveSend()
{
Interlocked.Decrement(ref m_ActiveSendingCount);
}
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. This trims down TickCount so it doesn't wrap
/// for the callers.
/// This trims it to a 12 day interval so don't let your frame time get too long.
/// </summary>
/// <returns></returns>
public static int EnvironmentTickCount()
{
return Environment.TickCount & EnvironmentTickCountMask;
}
const int EnvironmentTickCountMask = 0x3fffffff;
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
/// 'EnvironmentTickCount()') and accounts for any wrapping.
/// </summary>
/// <param name="newValue"></param>
/// <param name="prevValue"></param>
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
public static int EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
{
int diff = newValue - prevValue;
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
}
/// <summary>
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
/// 'EnvironmentTickCount()') and accounts for any wrapping.
/// </summary>
/// <param name="newValue"></param>
/// <param name="prevValue"></param>
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
public static int EnvironmentTickCountAdd(Int32 newValue, Int32 prevValue)
{
int ret = newValue + prevValue;
return (ret >= 0) ? ret : (ret + EnvironmentTickCountMask + 1);
}
public static double TimeStampClockPeriodMS;
public static double TimeStampClockPeriod;
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static double GetTimeStamp()
{
return Stopwatch.GetTimestamp() * TimeStampClockPeriod;
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static double GetTimeStampMS()
{
return Stopwatch.GetTimestamp() * TimeStampClockPeriodMS;
}
// doing math in ticks is usefull to avoid loss of resolution
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static long GetTimeStampTicks()
{
return Stopwatch.GetTimestamp();
}
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
public static double TimeStampTicksToMS(long ticks)
{
return ticks * TimeStampClockPeriodMS;
}
}
}

View File

@ -1,29 +0,0 @@
using System;
namespace OSHttpServer
{
/// <summary>
/// An unhandled exception have been caught by the system.
/// </summary>
public class ExceptionEventArgs : EventArgs
{
private readonly Exception _exception;
/// <summary>
/// Initializes a new instance of the <see cref="ExceptionEventArgs"/> class.
/// </summary>
/// <param name="exception">Caught exception.</param>
public ExceptionEventArgs(Exception exception)
{
_exception = exception;
}
/// <summary>
/// caught exception
/// </summary>
public Exception Exception
{
get { return _exception; }
}
}
}

View File

@ -1,16 +0,0 @@
using System;
namespace OSHttpServer
{
/// <summary>
/// We dont want to let the server to die due to exceptions thrown in worker threads.
/// therefore we use this delegate to give you a change to handle uncaught exceptions.
/// </summary>
/// <param name="source">Class that the exception was thrown in.</param>
/// <param name="exception">Exception</param>
/// <remarks>
/// Server will throw a InternalServerException in release version if you dont
/// handle this delegate.
/// </remarks>
public delegate void ExceptionHandler(object source, Exception exception);
}

View File

@ -1,25 +0,0 @@
using System.Net;
namespace OSHttpServer.Exceptions
{
/// <summary>
/// The server understood the request, but is refusing to fulfill it.
/// Authorization will not help and the request SHOULD NOT be repeated.
/// If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled,
/// it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information
/// available to the client, the status code 404 (Not Found) can be used instead.
///
/// Text taken from: http://www.submissionchamber.com/help-guides/error-codes.php
/// </summary>
public class ForbiddenException : HttpException
{
/// <summary>
/// Initializes a new instance of the <see cref="ForbiddenException"/> class.
/// </summary>
/// <param name="errorMsg">error message</param>
public ForbiddenException(string errorMsg)
: base(HttpStatusCode.Forbidden, errorMsg)
{
}
}
}

View File

@ -1,38 +0,0 @@
using System;
namespace OSHttpServer.Parser
{
/// <summary>
/// Event arguments used when a new header have been parsed.
/// </summary>
public class HeaderEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="HeaderEventArgs"/> class.
/// </summary>
/// <param name="name">Name of header.</param>
/// <param name="value">Header value.</param>
public HeaderEventArgs(string name, string value)
{
Name = name;
Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="HeaderEventArgs"/> class.
/// </summary>
public HeaderEventArgs()
{
}
/// <summary>
/// Gets or sets header name.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets header value.
/// </summary>
public string Value { get; set; }
}
}

View File

@ -1,739 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using OSHttpServer.Exceptions;
using OSHttpServer.Parser;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace OSHttpServer
{
/// <summary>
/// Contains a connection to a browser/client.
/// </summary>
/// <remarks>
/// Remember to <see cref="Start"/> after you have hooked the <see cref="RequestReceived"/> event.
/// </remarks>
public class HttpClientContext : IHttpClientContext, IDisposable
{
const int MAXREQUESTS = 20;
const int MAXKEEPALIVE = 120000;
static private int basecontextID;
Queue<HttpRequest> m_requests;
object m_requestsLock = new object();
public int m_maxRequests = MAXREQUESTS;
public bool m_waitingResponse;
private readonly byte[] m_ReceiveBuffer;
private int m_ReceiveBytesLeft;
private ILogWriter m_log;
private readonly IHttpRequestParser m_parser;
private Socket m_sock;
public bool Available = true;
public bool StreamPassedOff = false;
public int LastActivityTimeMS = 0;
public int MonitorKeepaliveStartMS = 0;
public bool TriggerKeepalive = false;
public int TimeoutFirstLine = 10000; // 10 seconds
public int TimeoutRequestReceived = 30000; // 30 seconds
public int TimeoutMaxIdle = 180000; // 3 minutes
public int m_TimeoutKeepAlive = 30000;
public bool FirstRequestLineReceived;
public bool FullRequestReceived;
private bool isSendingResponse = false;
private bool m_isClosing = false;
private HttpRequest m_currentRequest;
private HttpResponse m_currentResponse;
public int contextID { get; private set; }
public int TimeoutKeepAlive
{
get { return m_TimeoutKeepAlive; }
set
{
m_TimeoutKeepAlive = (value > MAXKEEPALIVE) ? MAXKEEPALIVE : value;
}
}
public bool IsClosing
{
get { return m_isClosing;}
}
public int MaxRequests
{
get { return m_maxRequests; }
set
{
if(value <= 1)
m_maxRequests = 1;
else
m_maxRequests = value > MAXREQUESTS ? MAXREQUESTS : value;
}
}
public bool IsSending()
{
return isSendingResponse;
}
public bool StopMonitoring;
public IPEndPoint LocalIPEndPoint {get; set;}
/// <summary>
/// Initializes a new instance of the <see cref="HttpClientContext"/> class.
/// </summary>
/// <param name="secured">true if the connection is secured (SSL/TLS)</param>
/// <param name="remoteEndPoint">client that connected.</param>
/// <param name="stream">Stream used for communication</param>
/// <param name="parserFactory">Used to create a <see cref="IHttpRequestParser"/>.</param>
/// <param name="bufferSize">Size of buffer to use when reading data. Must be at least 4096 bytes.</param>
/// <exception cref="SocketException">If <see cref="Socket.BeginReceive(byte[],int,int,SocketFlags,AsyncCallback,object)"/> fails</exception>
/// <exception cref="ArgumentException">Stream must be writable and readable.</exception>
public HttpClientContext(bool secured, IPEndPoint remoteEndPoint,
Stream stream, ILogWriter m_logWriter, Socket sock)
{
if (!stream.CanWrite || !stream.CanRead)
throw new ArgumentException("Stream must be writable and readable.");
LocalIPEndPoint = remoteEndPoint;
m_log = m_logWriter;
m_isClosing = false;
m_parser = new HttpRequestParser(m_log);
m_parser.RequestCompleted += OnRequestCompleted;
m_parser.RequestLineReceived += OnRequestLine;
m_parser.HeaderReceived += OnHeaderReceived;
m_parser.BodyBytesReceived += OnBodyBytesReceived;
m_currentRequest = new HttpRequest(this);
IsSecured = secured;
m_stream = stream;
m_sock = sock;
m_ReceiveBuffer = new byte[16384];
m_requests = new Queue<HttpRequest>();
SSLCommonName = "";
if (secured)
{
SslStream _ssl = (SslStream)m_stream;
X509Certificate _cert1 = _ssl.RemoteCertificate;
if (_cert1 != null)
{
X509Certificate2 _cert2 = new X509Certificate2(_cert1);
if (_cert2 != null)
SSLCommonName = _cert2.GetNameInfo(X509NameType.SimpleName, false);
}
}
++basecontextID;
if (basecontextID <= 0)
basecontextID = 1;
contextID = basecontextID;
sock.NoDelay = true;
}
public bool CanSend()
{
if (contextID < 0 || m_isClosing)
return false;
if (m_stream == null || m_sock == null || !m_sock.Connected)
return false;
return true;
}
/// <summary>
/// Process incoming body bytes.
/// </summary>
/// <param name="sender"><see cref="IHttpRequestParser"/></param>
/// <param name="e">Bytes</param>
protected virtual void OnBodyBytesReceived(object sender, BodyEventArgs e)
{
m_currentRequest.AddToBody(e.Buffer, e.Offset, e.Count);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void OnHeaderReceived(object sender, HeaderEventArgs e)
{
if (string.Compare(e.Name, "expect", true) == 0 && e.Value.Contains("100-continue"))
{
lock (m_requestsLock)
{
if (m_maxRequests == MAXREQUESTS)
Respond("HTTP/1.1", HttpStatusCode.Continue, null);
}
}
m_currentRequest.AddHeader(e.Name, e.Value);
}
private void OnRequestLine(object sender, RequestLineEventArgs e)
{
m_currentRequest.Method = e.HttpMethod;
m_currentRequest.HttpVersion = e.HttpVersion;
m_currentRequest.UriPath = e.UriPath;
m_currentRequest.AddHeader("remote_addr", LocalIPEndPoint.Address.ToString());
m_currentRequest.AddHeader("remote_port", LocalIPEndPoint.Port.ToString());
m_currentRequest.ArrivalTS = ContextTimeoutManager.GetTimeStamp();
FirstRequestLineReceived = true;
TriggerKeepalive = false;
MonitorKeepaliveStartMS = 0;
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
}
/// <summary>
/// Start reading content.
/// </summary>
/// <remarks>
/// Make sure to call base.Start() if you override this method.
/// </remarks>
public virtual void Start()
{
Task tk = new Task(() => ReceiveLoop());
tk.Start();
}
/// <summary>
/// Clean up context.
/// </summary>
/// <remarks>
/// </remarks>
public virtual void Cleanup()
{
if (StreamPassedOff)
return;
contextID = -100;
if (m_stream != null)
{
m_stream.Close();
m_stream = null;
m_sock = null;
}
m_currentRequest?.Clear();
m_currentRequest = null;
m_currentResponse?.Clear();
m_currentResponse = null;
if(m_requests != null)
{
while(m_requests.Count > 0)
{
HttpRequest req = m_requests.Dequeue();
req.Clear();
}
}
m_requests.Clear();
m_requests = null;
m_parser.Clear();
FirstRequestLineReceived = false;
FullRequestReceived = false;
LastActivityTimeMS = 0;
StopMonitoring = true;
MonitorKeepaliveStartMS = 0;
TriggerKeepalive = false;
isSendingResponse = false;
m_ReceiveBytesLeft = 0;
}
public void Close()
{
Dispose();
}
/// <summary>
/// Using SSL or other encryption method.
/// </summary>
[Obsolete("Use IsSecured instead.")]
public bool Secured
{
get { return IsSecured; }
}
/// <summary>
/// Using SSL or other encryption method.
/// </summary>
public bool IsSecured { get; internal set; }
// returns the SSL commonName of remote Certificate
public string SSLCommonName { get; internal set; }
/// <summary>
/// Specify which logger to use.
/// </summary>
public ILogWriter LogWriter
{
get { return m_log; }
set
{
m_log = value ?? NullLogWriter.Instance;
m_parser.LogWriter = m_log;
}
}
private Stream m_stream;
/// <summary>
/// Gets or sets the network stream.
/// </summary>
internal Stream Stream
{
get { return m_stream; }
set { m_stream = value; }
}
/// <summary>
/// Disconnect from client
/// </summary>
/// <param name="error">error to report in the <see cref="Disconnected"/> event.</param>
public void Disconnect(SocketError error)
{
// disconnect may not throw any exceptions
try
{
try
{
if (m_stream != null)
{
if (error == SocketError.Success)
{
try
{
m_stream.Flush();
}
catch { }
}
m_stream.Close();
m_stream = null;
}
m_sock = null;
}
catch { }
Disconnected?.Invoke(this, new DisconnectedEventArgs(error));
}
catch (Exception err)
{
LogWriter.Write(this, LogPrio.Error, "Disconnect threw an exception: " + err);
}
}
private async void ReceiveLoop()
{
m_ReceiveBytesLeft = 0;
try
{
while(true)
{
if (m_stream == null || !m_stream.CanRead)
return;
int bytesRead = await m_stream.ReadAsync(m_ReceiveBuffer, m_ReceiveBytesLeft, m_ReceiveBuffer.Length - m_ReceiveBytesLeft).ConfigureAwait(false);
if (bytesRead == 0)
{
Disconnect(SocketError.Success);
return;
}
if(m_isClosing)
continue;
m_ReceiveBytesLeft += bytesRead;
int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft);
if (m_stream == null)
return; // "Connection: Close" in effect.
while (offset != 0)
{
int nextBytesleft = m_ReceiveBytesLeft - offset;
if(nextBytesleft <= 0)
break;
int nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft);
if (m_stream == null)
return; // "Connection: Close" in effect.
if (nextOffset == 0)
break;
offset = nextOffset;
}
// copy unused bytes to the beginning of the array
if (offset > 0 && m_ReceiveBytesLeft > offset)
Buffer.BlockCopy(m_ReceiveBuffer, offset, m_ReceiveBuffer, 0, m_ReceiveBytesLeft - offset);
m_ReceiveBytesLeft -= offset;
if (StreamPassedOff)
return; //?
}
}
catch (BadRequestException err)
{
LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err);
try
{
Respond("HTTP/1.1", HttpStatusCode.BadRequest, err.Message);
}
catch (Exception err2)
{
LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2);
}
//Disconnect(SocketError.NoRecovery);
Disconnect(SocketError.Success); // try to flush
}
catch (IOException err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message);
if (err.InnerException is SocketException)
Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode);
else
Disconnect(SocketError.ConnectionReset);
}
catch (ObjectDisposedException err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message);
Disconnect(SocketError.NotSocket);
}
catch (NullReferenceException err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message);
Disconnect(SocketError.NoRecovery);
}
catch (Exception err)
{
LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message);
Disconnect(SocketError.NoRecovery);
}
}
private void OnRequestCompleted(object source, EventArgs args)
{
TriggerKeepalive = false;
MonitorKeepaliveStartMS = 0;
FullRequestReceived = true;
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
if (m_maxRequests == 0)
return;
if (--m_maxRequests == 0)
m_currentRequest.Connection = ConnectionType.Close;
if(m_currentRequest.Uri == null)
{
// should not happen
try
{
Uri uri = new Uri(m_currentRequest.Secure ? "https://" : "http://" + m_currentRequest.UriPath);
m_currentRequest.Uri = uri;
m_currentRequest.UriPath = uri.AbsolutePath;
}
catch
{
return;
}
}
// load cookies if they exist
if(m_currentRequest.Headers["cookie"] != null)
m_currentRequest.SetCookies(new RequestCookies(m_currentRequest.Headers["cookie"]));
m_currentRequest.Body.Seek(0, SeekOrigin.Begin);
bool donow = true;
lock (m_requestsLock)
{
if(m_waitingResponse)
{
m_requests.Enqueue(m_currentRequest);
donow = false;
}
else
m_waitingResponse = true;
}
if(donow)
RequestReceived?.Invoke(this, new RequestEventArgs(m_currentRequest));
m_currentRequest = new HttpRequest(this);
}
public void StartSendResponse(HttpResponse response)
{
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
isSendingResponse = true;
m_currentResponse = response;
ContextTimeoutManager.EnqueueSend(this, response.Priority);
}
public bool TrySendResponse(int bytesLimit)
{
if(m_currentResponse == null)
return false;
if (m_currentResponse.Sent)
return false;
if(!CanSend())
return false;
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
m_currentResponse?.SendNextAsync(bytesLimit);
return false;
}
public void ContinueSendResponse(bool notThrottled)
{
if(m_currentResponse == null)
return;
ContextTimeoutManager.EnqueueSend(this, m_currentResponse.Priority, notThrottled);
}
public void EndSendResponse(uint requestID, ConnectionType ctype)
{
isSendingResponse = false;
m_currentResponse?.Clear();
m_currentResponse = null;
lock (m_requestsLock)
m_waitingResponse = false;
if(contextID < 0)
return;
if (ctype == ConnectionType.Close)
{
m_isClosing = true;
m_requests.Clear();
TriggerKeepalive = true;
return;
}
else
{
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
if (Stream == null || !Stream.CanWrite)
return;
HttpRequest nextRequest = null;
lock (m_requestsLock)
{
if (m_requests != null && m_requests.Count > 0)
nextRequest = m_requests.Dequeue();
if (nextRequest != null && RequestReceived != null)
{
m_waitingResponse = true;
TriggerKeepalive = false;
}
else
TriggerKeepalive = true;
}
if (nextRequest != null)
RequestReceived?.Invoke(this, new RequestEventArgs(nextRequest));
}
}
/// <summary>
/// Send a response.
/// </summary>
/// <param name="httpVersion">Either <see cref="HttpHelper.HTTP10"/> or <see cref="HttpHelper.HTTP11"/></param>
/// <param name="statusCode">HTTP status code</param>
/// <param name="reason">reason for the status code.</param>
/// <param name="body">HTML body contents, can be null or empty.</param>
/// <param name="contentType">A content type to return the body as, i.e. 'text/html' or 'text/plain', defaults to 'text/html' if null or empty</param>
/// <exception cref="ArgumentException">If <paramref name="httpVersion"/> is invalid.</exception>
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType)
{
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
if (string.IsNullOrEmpty(reason))
reason = statusCode.ToString();
byte[] buffer;
if(string.IsNullOrEmpty(body))
buffer = Encoding.ASCII.GetBytes(httpVersion + " " + (int)statusCode + " " + reason + "\r\n\r\n");
else
{
if (string.IsNullOrEmpty(contentType))
contentType = "text/html";
buffer = Encoding.UTF8.GetBytes(
string.Format("{0} {1} {2}\r\nContent-Type: {5}\r\nContent-Length: {3}\r\n\r\n{4}",
httpVersion, (int)statusCode, reason ?? statusCode.ToString(),
body.Length, body, contentType));
}
Send(buffer);
}
/// <summary>
/// Send a response.
/// </summary>
/// <param name="httpVersion">Either <see cref="HttpHelper.HTTP10"/> or <see cref="HttpHelper.HTTP11"/></param>
/// <param name="statusCode">HTTP status code</param>
/// <param name="reason">reason for the status code.</param>
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason)
{
if (string.IsNullOrEmpty(reason))
reason = statusCode.ToString();
byte[] buffer = Encoding.ASCII.GetBytes(httpVersion + " " + (int)statusCode + " " + reason + "\r\n\r\n");
Send(buffer);
}
/// <summary>
/// send a whole buffer
/// </summary>
/// <param name="buffer">buffer to send</param>
/// <exception cref="ArgumentNullException"></exception>
public bool Send(byte[] buffer)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
return Send(buffer, 0, buffer.Length);
}
/// <summary>
/// Send data using the stream
/// </summary>
/// <param name="buffer">Contains data to send</param>
/// <param name="offset">Start position in buffer</param>
/// <param name="size">number of bytes to send</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
private object sendLock = new object();
public bool Send(byte[] buffer, int offset, int size)
{
if (m_stream == null || m_sock == null || !m_sock.Connected)
return false;
if (offset + size > buffer.Length)
throw new ArgumentOutOfRangeException("offset", offset, "offset + size is beyond end of buffer.");
LastActivityTimeMS = ContextTimeoutManager.EnvironmentTickCount();
bool ok = true;
ContextTimeoutManager.ContextEnterActiveSend();
lock (sendLock) // can't have overlaps here
{
try
{
m_stream.Write(buffer, offset, size);
}
catch
{
ok = false;
}
}
ContextTimeoutManager.ContextLeaveActiveSend();
if (!ok && m_stream != null)
Disconnect(SocketError.NoRecovery);
return ok;
}
public async Task<bool> SendAsync(byte[] buffer, int offset, int size)
{
if (m_stream == null || m_sock == null || !m_sock.Connected)
return false;
if (offset + size > buffer.Length)
throw new ArgumentOutOfRangeException("offset", offset, "offset + size is beyond end of buffer.");
bool ok = true;
ContextTimeoutManager.ContextEnterActiveSend();
try
{
await m_stream.WriteAsync(buffer, offset, size).ConfigureAwait(false);
}
catch
{
ok = false;
}
ContextTimeoutManager.ContextLeaveActiveSend();
if (!ok && m_stream != null)
Disconnect(SocketError.NoRecovery);
return ok;
}
/// <summary>
/// The context have been disconnected.
/// </summary>
/// <remarks>
/// Event can be used to clean up a context, or to reuse it.
/// </remarks>
public event EventHandler<DisconnectedEventArgs> Disconnected;
/// <summary>
/// A request have been received in the context.
/// </summary>
public event EventHandler<RequestEventArgs> RequestReceived;
public HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing()
{
StreamPassedOff = true;
m_parser.RequestCompleted -= OnRequestCompleted;
m_parser.RequestLineReceived -= OnRequestLine;
m_parser.HeaderReceived -= OnHeaderReceived;
m_parser.BodyBytesReceived -= OnBodyBytesReceived;
m_parser.Clear();
m_currentRequest?.Clear();
m_currentRequest = null;
m_currentResponse?.Clear();
m_currentResponse = null;
if (m_requests != null)
{
while (m_requests.Count > 0)
{
HttpRequest req = m_requests.Dequeue();
req.Clear();
}
}
m_requests.Clear();
m_requests = null;
return new HTTPNetworkContext() { Socket = m_sock, Stream = m_stream as NetworkStream };
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (contextID >= 0)
{
StreamPassedOff = false;
Cleanup();
}
}
}
}

View File

@ -1,173 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
namespace OSHttpServer
{
/// <summary>
/// Used to create and reuse contexts.
/// </summary>
public class HttpContextFactory : IHttpContextFactory
{
private readonly ConcurrentDictionary<int, HttpClientContext> m_activeContexts = new ConcurrentDictionary<int, HttpClientContext>();
private readonly ILogWriter m_logWriter;
/// <summary>
/// A request have been received from one of the contexts.
/// </summary>
public event EventHandler<RequestEventArgs> RequestReceived;
/// <summary>
/// Initializes a new instance of the <see cref="HttpContextFactory"/> class.
/// </summary>
/// <param name="writer">The writer.</param>
/// <param name="bufferSize">Amount of bytes to read from the incoming socket stream.</param>
/// <param name="factory">Used to create a request parser.</param>
public HttpContextFactory(ILogWriter writer)
{
m_logWriter = writer;
ContextTimeoutManager.Start();
}
/// <summary>
/// Create a new context.
/// </summary>
/// <param name="isSecured">true if socket is running HTTPS.</param>
/// <param name="endPoint">Client that connected</param>
/// <param name="stream">Network/SSL stream.</param>
/// <returns>A context.</returns>
protected HttpClientContext CreateContext(bool isSecured, IPEndPoint endPoint, Stream stream, Socket sock)
{
var context = new HttpClientContext(isSecured, endPoint, stream, m_logWriter, sock);
context.Disconnected += OnFreeContext;
context.RequestReceived += OnRequestReceived;
ContextTimeoutManager.StartMonitoringContext(context);
m_activeContexts[context.contextID] = context;
context.Start();
return context;
}
private void OnRequestReceived(object sender, RequestEventArgs e)
{
RequestReceived?.Invoke(sender, e);
}
private void OnFreeContext(object sender, DisconnectedEventArgs e)
{
var imp = sender as HttpClientContext;
if (imp == null || imp.contextID < 0)
return;
m_activeContexts.TryRemove(imp.contextID, out HttpClientContext dummy);
imp.Close();
}
#region IHttpContextFactory Members
/// <summary>
/// Create a secure <see cref="IHttpClientContext"/>.
/// </summary>
/// <param name="socket">Client socket (accepted by the <see cref="OSHttpListener"/>).</param>
/// <param name="certificate">HTTPS certificate to use.</param>
/// <param name="protocol">Kind of HTTPS protocol. Usually TLS or SSL.</param>
/// <returns>
/// A created <see cref="IHttpClientContext"/>.
/// </returns>
public IHttpClientContext CreateSecureContext(Socket socket, X509Certificate certificate,
SslProtocols protocol, RemoteCertificateValidationCallback _clientCallback = null)
{
var networkStream = new NetworkStream(socket, true);
var remoteEndPoint = (IPEndPoint)socket.RemoteEndPoint;
SslStream sslStream = null;
try
{
if (_clientCallback == null)
{
sslStream = new SslStream(networkStream, false);
sslStream.AuthenticateAsServer(certificate, false, protocol, false);
}
else
{
sslStream = new SslStream(networkStream, false,
new RemoteCertificateValidationCallback(_clientCallback));
sslStream.AuthenticateAsServer(certificate, true, protocol, false);
}
}
catch (Exception e)
{
m_logWriter.Write(this, LogPrio.Error, e.Message);
sslStream.Close();
return null;
}
return CreateContext(true, remoteEndPoint, sslStream, socket);
}
/// <summary>
/// Creates a <see cref="IHttpClientContext"/> that handles a connected client.
/// </summary>
/// <param name="socket">Client socket (accepted by the <see cref="OSHttpListener"/>).</param>
/// <returns>
/// A creates <see cref="IHttpClientContext"/>.
/// </returns>
public IHttpClientContext CreateContext(Socket socket)
{
socket.NoDelay = true;
var networkStream = new NetworkStream(socket, true);
var remoteEndPoint = (IPEndPoint)socket.RemoteEndPoint;
return CreateContext(false, remoteEndPoint, networkStream, socket);
}
#endregion
/// <summary>
/// Server is shutting down so shut down the factory
/// </summary>
public void Shutdown()
{
ContextTimeoutManager.Stop();
}
}
/// <summary>
/// Used to create <see cref="IHttpClientContext"/>es.
/// </summary>
public interface IHttpContextFactory
{
/// <summary>
/// Creates a <see cref="IHttpClientContext"/> that handles a connected client.
/// </summary>
/// <param name="socket">Client socket (accepted by the <see cref="OSHttpListener"/>).</param>
/// <returns>A creates <see cref="IHttpClientContext"/>.</returns>
IHttpClientContext CreateContext(Socket socket);
/// <summary>
/// Create a secure <see cref="IHttpClientContext"/>.
/// </summary>
/// <param name="socket">Client socket (accepted by the <see cref="OSHttpListener"/>).</param>
/// <param name="certificate">HTTPS certificate to use.</param>
/// <param name="protocol">Kind of HTTPS protocol. Usually TLS or SSL.</param>
/// <returns>A created <see cref="IHttpClientContext"/>.</returns>
IHttpClientContext CreateSecureContext(Socket socket, X509Certificate certificate,
SslProtocols protocol, RemoteCertificateValidationCallback _clientCallback = null);
/// <summary>
/// A request have been received from one of the contexts.
/// </summary>
event EventHandler<RequestEventArgs> RequestReceived;
/// <summary>
/// Server is shutting down so shut down the factory
/// </summary>
void Shutdown();
}
}

View File

@ -1,43 +0,0 @@
using System;
using System.Net;
namespace OSHttpServer.Exceptions
{
/// <summary>
/// All HTTP based exceptions will derive this class.
/// </summary>
public class HttpException : Exception
{
private readonly HttpStatusCode _code;
/// <summary>
/// Create a new HttpException
/// </summary>
/// <param name="code">http status code (sent in the response)</param>
/// <param name="message">error description</param>
public HttpException(HttpStatusCode code, string message) : base(code + ": " + message)
{
_code = code;
}
/// <summary>
/// Create a new HttpException
/// </summary>
/// <param name="code">http status code (sent in the response)</param>
/// <param name="message">error description</param>
/// <param name="inner">inner exception</param>
public HttpException(HttpStatusCode code, string message, Exception inner)
: base(code + ": " + message, inner)
{
_code = code;
}
/// <summary>
/// status code to use in the response.
/// </summary>
public HttpStatusCode HttpStatusCode
{
get { return _code; }
}
}
}

View File

@ -1,263 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace OSHttpServer
{
/// <summary>
/// Contains some kind of input from the browser/client.
/// can be QueryString, form data or any other request body content.
/// </summary>
public class HttpInput : IHttpInput
{
/// <summary> Representation of a non-initialized class instance </summary>
public static readonly HttpInput Empty = new HttpInput("Empty", true);
private readonly IDictionary<string, HttpInputItem> _items = new Dictionary<string, HttpInputItem>();
private string _name;
/// <summary> Variable telling the class that it is non-initialized <see cref="Empty"/> </summary>
protected readonly bool _ignoreChanges;
/// <summary>
/// Initializes a new instance of the <see cref="HttpInput"/> class.
/// </summary>
/// <param name="name">form name.</param>
public HttpInput(string name)
{
Name = name;
}
/// <summary>
/// Initializes a new instance of the <see cref="HttpInput"/> class.
/// </summary>
/// <param name="name">form name.</param>
/// <param name="ignoreChanges">if set to <c>true</c> all changes will be ignored. </param>
/// <remarks>this constructor should only be used by Empty</remarks>
protected HttpInput(string name, bool ignoreChanges)
{
_name = name;
_ignoreChanges = ignoreChanges;
}
/// <summary>Creates a deep copy of the HttpInput class</summary>
/// <param name="input">The object to copy</param>
/// <remarks>The function makes a deep copy of quite a lot which can be slow</remarks>
protected HttpInput(HttpInput input)
{
foreach (HttpInputItem item in input)
_items.Add(item.Name, new HttpInputItem(item));
_name = input._name;
_ignoreChanges = input._ignoreChanges;
}
/// <summary>
/// Form name as lower case
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}
/// <summary>
/// Add a new element. Form array elements are parsed
/// and added in a correct hierarchy.
/// </summary>
/// <param name="name">Name is converted to lower case.</param>
/// <param name="value"></param>
/// <exception cref="ArgumentNullException"><c>name</c> is null.</exception>
/// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
public void Add(string name, string value)
{
if (name == null)
throw new ArgumentNullException("name");
if (_ignoreChanges)
throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
// Check if it's a sub item.
// we can have multiple levels of sub items as in user[extension[id]] => user -> extension -> id
int pos = name.IndexOf('[');
if (pos != -1)
{
string name1 = name.Substring(0, pos);
string name2 = ExtractOne(name);
if (!_items.ContainsKey(name1))
_items.Add(name1, new HttpInputItem(name1, null));
_items[name1].Add(name2, value);
}
else
{
if (_items.ContainsKey(name))
_items[name].Add(value);
else
_items.Add(name, new HttpInputItem(name, value));
}
}
/// <summary>
/// Get a form item.
/// </summary>
/// <param name="name"></param>
/// <returns>Returns <see cref="HttpInputItem.Empty"/> if item was not found.</returns>
public HttpInputItem this[string name]
{
get
{
return _items.ContainsKey(name) ? _items[name] : HttpInputItem.Empty;
}
}
/// <summary>
/// Returns true if the class contains a <see cref="HttpInput"/> with the corresponding name.
/// </summary>
/// <param name="name">The field/query string name</param>
/// <returns>True if the value exists</returns>
public bool Contains(string name)
{
return _items.ContainsKey(name) && _items[name].Value != null;
}
/// <summary>
/// Parses an item and returns it.
/// This function is primarily used to parse array items as in user[name].
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public static HttpInputItem ParseItem(string name, string value)
{
HttpInputItem item;
// Check if it's a sub item.
// we can have multiple levels of sub items as in user[extension[id]]] => user -> extension -> id
int pos = name.IndexOf('[');
if (pos != -1)
{
string name1 = name.Substring(0, pos);
string name2 = ExtractOne(name);
item = new HttpInputItem(name1, null);
item.Add(name2, value);
}
else
item = new HttpInputItem(name, value);
return item;
}
/// <summary> Outputs the instance representing all its values joined together </summary>
/// <returns></returns>
public override string ToString()
{
string temp = string.Empty;
foreach (KeyValuePair<string, HttpInputItem> item in _items)
temp += item.Value.ToString(Name);
return temp;
}
/// <summary>Returns all items as an unescaped query string.</summary>
/// <returns></returns>
public string ToString(bool asQueryString)
{
if (!asQueryString)
return ToString();
string temp = string.Empty;
foreach (KeyValuePair<string, HttpInputItem> item in _items)
temp += item.Value.ToString(null, true) + '&';
return temp.Length > 0 ? temp.Substring(0, temp.Length - 1) : string.Empty;
}
/// <summary>
/// Extracts one parameter from an array
/// </summary>
/// <param name="value">Containing the string array</param>
/// <returns>All but the first value</returns>
/// <example>
/// string test1 = ExtractOne("system[user][extension][id]");
/// string test2 = ExtractOne(test1);
/// string test3 = ExtractOne(test2);
/// // test1 = user[extension][id]
/// // test2 = extension[id]
/// // test3 = id
/// </example>
public static string ExtractOne(string value)
{
int pos = value.IndexOf('[');
if (pos != -1)
{
++pos;
int gotMore = value.IndexOf('[', pos + 1);
if (gotMore != -1)
value = value.Substring(pos, gotMore - pos - 1) + value.Substring(gotMore);
else
value = value.Substring(pos, value.Length - pos - 1);
}
return value;
}
/// <summary>Resets all data contained by class</summary>
virtual public void Clear()
{
_name = string.Empty;
_items.Clear();
}
///<summary>
///Returns an enumerator that iterates through the collection.
///</summary>
///
///<returns>
///A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
///</returns>
///<filterpriority>1</filterpriority>
IEnumerator<HttpInputItem> IEnumerable<HttpInputItem>.GetEnumerator()
{
return _items.Values.GetEnumerator();
}
///<summary>
///Returns an enumerator that iterates through a collection.
///</summary>
///
///<returns>
///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
///</returns>
///<filterpriority>2</filterpriority>
public IEnumerator GetEnumerator()
{
return _items.Values.GetEnumerator();
}
}
/// <summary>
/// Base class for request data containers
/// </summary>
public interface IHttpInput : IEnumerable<HttpInputItem>
{
/// <summary>
/// Adds a parameter mapped to the presented name
/// </summary>
/// <param name="name">The name to map the parameter to</param>
/// <param name="value">The parameter value</param>
void Add(string name, string value);
/// <summary>
/// Returns a request parameter
/// </summary>
/// <param name="name">The name associated with the parameter</param>
/// <returns></returns>
HttpInputItem this[string name]
{ get; }
/// <summary>
/// Returns true if the container contains the requested parameter
/// </summary>
/// <param name="name">Parameter id</param>
/// <returns>True if parameter exists</returns>
bool Contains(string name);
}
}

View File

@ -1,309 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace OSHttpServer
{
/// <summary>
/// represents a HTTP input item. Each item can have multiple sub items, a sub item
/// is made in a HTML form by using square brackets
/// </summary>
/// <example>
/// // <input type="text" name="user[FirstName]" value="jonas" /> becomes:
/// Console.WriteLine("Value: {0}", form["user"]["FirstName"].Value);
/// </example>
/// <remarks>
/// All names in a form SHOULD be in lowercase.
/// </remarks>
public class HttpInputItem : IHttpInput
{
/// <summary> Representation of a non-initialized <see cref="HttpInputItem"/>.</summary>
public static readonly HttpInputItem Empty = new HttpInputItem(string.Empty, true);
private readonly IDictionary<string, HttpInputItem> _items = new Dictionary<string, HttpInputItem>();
private readonly List<string> _values = new List<string>();
private string _name;
private readonly bool _ignoreChanges;
/// <summary>
/// Initializes an input item setting its name/identifier and value
/// </summary>
/// <param name="name">Parameter name/id</param>
/// <param name="value">Parameter value</param>
public HttpInputItem(string name, string value)
{
Name = name;
Add(value);
}
private HttpInputItem(string name, bool ignore)
{
Name = name;
_ignoreChanges = ignore;
}
/// <summary>Creates a deep copy of the item specified</summary>
/// <param name="item">The item to copy</param>
/// <remarks>The function makes a deep copy of quite a lot which can be slow</remarks>
public HttpInputItem(HttpInputItem item)
{
foreach (KeyValuePair<string, HttpInputItem> pair in item._items)
_items.Add(pair.Key, pair.Value);
foreach (string value in item._values)
_values.Add(value);
_ignoreChanges = item._ignoreChanges;
_name = item.Name;
}
/// <summary>
/// Number of values
/// </summary>
public int Count
{
get { return _values.Count; }
}
/// <summary>
/// Get a sub item
/// </summary>
/// <param name="name">name in lower case.</param>
/// <returns><see cref="HttpInputItem.Empty"/> if no item was found.</returns>
public HttpInputItem this[string name]
{
get {
return _items.ContainsKey(name) ? _items[name] : Empty;
}
}
/// <summary>
/// Name of item (in lower case).
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}
/// <summary>
/// Returns the first value, or null if no value exist.
/// </summary>
public string Value
{
get {
return _values.Count == 0 ? null : _values[0];
}
set
{
if (_values.Count == 0)
_values.Add(value);
else
_values[0] = value;
}
}
/// <summary>
/// Returns the last value, or null if no value exist.
/// </summary>
public string LastValue
{
get
{
return _values.Count == 0 ? null : _values[_values.Count - 1];
}
}
/// <summary>
/// Returns the list with values.
/// </summary>
public IList<string> Values
{
get { return _values.AsReadOnly(); }
}
/// <summary>
/// Add another value to this item
/// </summary>
/// <param name="value">Value to add.</param>
/// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
public void Add(string value)
{
if (value == null)
return;
if (_ignoreChanges)
throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
_values.Add(value);
}
/// <summary>
/// checks if a sub-item exists (and has a value).
/// </summary>
/// <param name="name">name in lower case</param>
/// <returns>true if the sub-item exists and has a value; otherwise false.</returns>
public bool Contains(string name)
{
return _items.ContainsKey(name) && _items[name].Value != null;
}
/// <summary> Returns a formatted representation of the instance with the values of all contained parameters </summary>
public override string ToString()
{
return ToString(string.Empty);
}
/// <summary>
/// Outputs the string in a formatted manner
/// </summary>
/// <param name="prefix">A prefix to append, used internally</param>
/// <param name="asQuerySting">produce a query string</param>
public string ToString(string prefix, bool asQuerySting)
{
string name;
if (string.IsNullOrEmpty(prefix))
name = Name;
else
name = prefix + "[" + Name + "]";
if (asQuerySting)
{
string temp;
if (_values.Count == 0 && _items.Count > 0)
temp = string.Empty;
else
temp = name;
if (_values.Count > 0)
{
temp += '=';
foreach (string value in _values)
temp += value + ',';
temp = temp.Remove(temp.Length - 1, 1);
}
foreach (KeyValuePair<string, HttpInputItem> item in _items)
temp += item.Value.ToString(name, true) + '&';
return _items.Count > 0 ? temp.Substring(0, temp.Length - 1) : temp;
}
else
{
string temp = name;
if (_values.Count > 0)
{
temp += " = ";
foreach (string value in _values)
temp += value + ", ";
temp = temp.Remove(temp.Length - 2, 2);
}
temp += Environment.NewLine;
foreach (KeyValuePair<string, HttpInputItem> item in _items)
temp += item.Value.ToString(name, false);
return temp;
}
}
#region IHttpInput Members
/// <summary>
///
/// </summary>
/// <param name="name">name in lower case</param>
/// <returns></returns>
HttpInputItem IHttpInput.this[string name]
{
get
{
return _items.ContainsKey(name) ? _items[name] : Empty;
}
}
/// <summary>
/// Add a sub item.
/// </summary>
/// <param name="name">Can contain array formatting, the item is then parsed and added in multiple levels</param>
/// <param name="value">Value to add.</param>
/// <exception cref="ArgumentNullException">Argument is null.</exception>
/// <exception cref="InvalidOperationException">Cannot add stuff to <see cref="HttpInput.Empty"/>.</exception>
public void Add(string name, string value)
{
if (name == null && value != null)
throw new ArgumentNullException("name");
if (name == null)
return;
if (_ignoreChanges)
throw new InvalidOperationException("Cannot add stuff to HttpInput.Empty.");
int pos = name.IndexOf('[');
if (pos != -1)
{
string name1 = name.Substring(0, pos);
string name2 = HttpInput.ExtractOne(name);
if (!_items.ContainsKey(name1))
_items.Add(name1, new HttpInputItem(name1, null));
_items[name1].Add(name2, value);
/*
HttpInputItem item = HttpInput.ParseItem(name, value);
// Add the value to an existing sub item
if (_items.ContainsKey(item.Name))
_items[item.Name].Add(item.Value);
else
_items.Add(item.Name, item);
*/
}
else
{
if (_items.ContainsKey(name))
_items[name].Add(value);
else
_items.Add(name, new HttpInputItem(name, value));
}
}
#endregion
///<summary>
///Returns an enumerator that iterates through the collection.
///</summary>
///
///<returns>
///A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
///</returns>
///<filterpriority>1</filterpriority>
IEnumerator<HttpInputItem> IEnumerable<HttpInputItem>.GetEnumerator()
{
return _items.Values.GetEnumerator();
}
#region IEnumerable Members
///<summary>
///Returns an enumerator that iterates through a collection.
///</summary>
///
///<returns>
///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
///</returns>
///<filterpriority>2</filterpriority>
public IEnumerator GetEnumerator()
{
return _items.Values.GetEnumerator();
}
#endregion
/// <summary>
/// Outputs the string in a formatted manner
/// </summary>
/// <param name="prefix">A prefix to append, used internally</param>
/// <returns></returns>
public string ToString(string prefix)
{
return ToString(prefix, false);
}
}
}

View File

@ -1,253 +0,0 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
namespace OSHttpServer
{
public class OSHttpListener: IDisposable
{
private readonly IPAddress m_address;
private readonly X509Certificate m_certificate;
private readonly IHttpContextFactory m_contextFactory;
private readonly int m_port;
private readonly ManualResetEvent m_shutdownEvent = new ManualResetEvent(false);
private readonly SslProtocols m_sslProtocol = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Ssl3 | SslProtocols.Ssl2;
private TcpListener m_listener;
private ILogWriter m_logWriter = NullLogWriter.Instance;
private int m_pendingAccepts;
private bool m_shutdown;
protected RemoteCertificateValidationCallback m_clientCertValCallback = null;
public event EventHandler<ClientAcceptedEventArgs> Accepted;
public event ExceptionHandler ExceptionThrown;
public event EventHandler<RequestEventArgs> RequestReceived;
/// <summary>
/// Listen for regular HTTP connections
/// </summary>
/// <param name="address">IP Address to accept connections on</param>
/// <param name="port">TCP Port to listen on, default HTTP port is 80.</param>
/// <param name="factory">Factory used to create <see cref="IHttpClientContext"/>es.</param>
/// <exception cref="ArgumentNullException"><c>address</c> is null.</exception>
/// <exception cref="ArgumentException">Port must be a positive number.</exception>
protected OSHttpListener(IPAddress address, int port)
{
m_address = address;
m_port = port;
m_contextFactory = new HttpContextFactory(m_logWriter);
m_contextFactory.RequestReceived += OnRequestReceived;
}
/// <summary>
/// Initializes a new instance of the <see cref="OSHttpListener"/> class.
/// </summary>
/// <param name="address">IP Address to accept connections on</param>
/// <param name="port">TCP Port to listen on, default HTTPS port is 443</param>
/// <param name="factory">Factory used to create <see cref="IHttpClientContext"/>es.</param>
/// <param name="certificate">Certificate to use</param>
protected OSHttpListener(IPAddress address, int port, X509Certificate certificate)
: this(address, port)
{
m_certificate = certificate;
}
/// <summary>
/// Initializes a new instance of the <see cref="OSHttpListener"/> class.
/// </summary>
/// <param name="address">IP Address to accept connections on</param>
/// <param name="port">TCP Port to listen on, default HTTPS port is 443</param>
/// <param name="factory">Factory used to create <see cref="IHttpClientContext"/>es.</param>
/// <param name="certificate">Certificate to use</param>
/// <param name="protocol">which HTTPS protocol to use, default is TLS.</param>
protected OSHttpListener(IPAddress address, int port, X509Certificate certificate,
SslProtocols protocol)
: this(address, port)
{
m_certificate = certificate;
m_sslProtocol = protocol;
}
public static OSHttpListener Create(IPAddress address, int port)
{
return new OSHttpListener(address, port);
}
public static OSHttpListener Create(IPAddress address, int port, X509Certificate certificate)
{
return new OSHttpListener(address, port, certificate);
}
public static OSHttpListener Create(IPAddress address, int port, X509Certificate certificate, SslProtocols protocol)
{
return new OSHttpListener(address, port, certificate, protocol);
}
private void OnRequestReceived(object sender, RequestEventArgs e)
{
RequestReceived?.Invoke(sender, e);
}
public RemoteCertificateValidationCallback CertificateValidationCallback
{
set { m_clientCertValCallback = value; }
}
/// <summary>
/// Gives you a change to receive log entries for all internals of the HTTP library.
/// </summary>
/// <remarks>
/// You may not switch log writer after starting the listener.
/// </remarks>
public ILogWriter LogWriter
{
get { return m_logWriter; }
set
{
m_logWriter = value ?? NullLogWriter.Instance;
if (m_certificate != null)
m_logWriter.Write(this, LogPrio.Info,
"HTTPS(" + m_sslProtocol + ") listening on " + m_address + ":" + m_port);
else
m_logWriter.Write(this, LogPrio.Info, "HTTP listening on " + m_address + ":" + m_port);
}
}
/// <summary>
/// True if we should turn on trace logs.
/// </summary>
public bool UseTraceLogs { get; set; }
/// <exception cref="Exception"><c>Exception</c>.</exception>
private void OnAccept(IAsyncResult ar)
{
bool beginAcceptCalled = false;
try
{
int count = Interlocked.Decrement(ref m_pendingAccepts);
if (m_shutdown)
{
if (count == 0)
m_shutdownEvent.Set();
return;
}
Interlocked.Increment(ref m_pendingAccepts);
m_listener.BeginAcceptSocket(OnAccept, null);
beginAcceptCalled = true;
Socket socket = m_listener.EndAcceptSocket(ar);
if (!socket.Connected)
{
socket.Dispose();
return;
}
if (!OnAcceptingSocket(socket))
{
socket.Disconnect(true);
return;
}
if(socket.Connected)
{
m_logWriter.Write(this, LogPrio.Debug, "Accepted connection from: " + socket.RemoteEndPoint);
if (m_certificate != null)
m_contextFactory.CreateSecureContext(socket, m_certificate, m_sslProtocol, m_clientCertValCallback);
else
m_contextFactory.CreateContext(socket);
}
else
socket.Dispose();
}
catch (Exception err)
{
m_logWriter.Write(this, LogPrio.Debug, err.Message);
ExceptionThrown?.Invoke(this, err);
if (!beginAcceptCalled)
RetryBeginAccept();
}
}
/// <summary>
/// Will try to accept connections one more time.
/// </summary>
/// <exception cref="Exception">If any exceptions is thrown.</exception>
private void RetryBeginAccept()
{
try
{
m_logWriter.Write(this, LogPrio.Error, "Trying to accept connections again.");
m_listener.BeginAcceptSocket(OnAccept, null);
}
catch (Exception err)
{
m_logWriter.Write(this, LogPrio.Fatal, err.Message);
ExceptionThrown?.Invoke(this, err);
}
}
/// <summary>
/// Can be used to create filtering of new connections.
/// </summary>
/// <param name="socket">Accepted socket</param>
/// <returns>true if connection can be accepted; otherwise false.</returns>
protected bool OnAcceptingSocket(Socket socket)
{
ClientAcceptedEventArgs args = new ClientAcceptedEventArgs(socket);
Accepted?.Invoke(this, args);
return !args.Revoked;
}
/// <summary>
/// Start listen for new connections
/// </summary>
/// <param name="backlog">Number of connections that can stand in a queue to be accepted.</param>
/// <exception cref="InvalidOperationException">Listener have already been started.</exception>
public void Start(int backlog)
{
if (m_listener != null)
throw new InvalidOperationException("Listener have already been started.");
m_listener = new TcpListener(m_address, m_port);
m_listener.Start(backlog);
Interlocked.Increment(ref m_pendingAccepts);
m_listener.BeginAcceptSocket(OnAccept, null);
}
/// <summary>
/// Stop the listener
/// </summary>
/// <exception cref="SocketException"></exception>
public void Stop()
{
m_shutdown = true;
m_contextFactory.Shutdown();
m_listener.Stop();
if (!m_shutdownEvent.WaitOne())
m_logWriter.Write(this, LogPrio.Error, "Failed to shutdown listener properly.");
m_listener = null;
Dispose();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (m_shutdownEvent != null)
{
m_shutdownEvent.Dispose();
}
}
}
}

View File

@ -1,114 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace OSHttpServer
{
/// <summary>
/// Returns item either from a form or a query string (checks them in that order)
/// </summary>
public class HttpParam : IHttpInput
{
/// <summary> Representation of a non-initialized HttpParam </summary>
public static readonly HttpParam Empty = new HttpParam(HttpInput.Empty, HttpInput.Empty);
private IHttpInput m_form;
private IHttpInput m_query;
private List<HttpInputItem> _items = new List<HttpInputItem>();
/// <summary>Initialises the class to hold a value either from a post request or a querystring request</summary>
public HttpParam(IHttpInput form, IHttpInput query)
{
m_form = form;
m_query = query;
}
#region IHttpInput Members
/// <summary>
/// The add method is not availible for HttpParam
/// since HttpParam checks both Request.Form and Request.QueryString
/// </summary>
/// <param name="name">name identifying the value</param>
/// <param name="value">value to add</param>
/// <exception cref="NotImplementedException"></exception>
[Obsolete("Not implemented for HttpParam")]
public void Add(string name, string value)
{
throw new NotImplementedException();
}
/// <summary>
/// Checks whether the form or querystring has the specified value
/// </summary>
/// <param name="name">Name, case sensitive</param>
/// <returns>true if found; otherwise false.</returns>
public bool Contains(string name)
{
return m_form.Contains(name) || m_query.Contains(name);
}
/// <summary>
/// Fetch an item from the form or querystring (in that order).
/// </summary>
/// <param name="name"></param>
/// <returns>Item if found; otherwise HttpInputItem.EmptyLanguageNode</returns>
public HttpInputItem this[string name]
{
get
{
if (m_form[name] != HttpInputItem.Empty)
return m_form[name];
else
return m_query[name];
}
}
#endregion
internal void SetQueryString(HttpInput query)
{
m_query = query;
}
internal void SetForm(HttpInput form)
{
m_form = form;
}
///<summary>
///Returns an enumerator that iterates through the collection.
///</summary>
///
///<returns>
///A <see cref="T:System.Collections.Generic.IEnumerator`1"></see> that can be used to iterate through the collection.
///</returns>
///<filterpriority>1</filterpriority>
IEnumerator<HttpInputItem> IEnumerable<HttpInputItem>.GetEnumerator()
{
List<HttpInputItem> items = new List<HttpInputItem>(m_query);
items.AddRange(m_form);
return items.GetEnumerator();
}
#region IEnumerable Members
///<summary>
///Returns an enumerator that iterates through a collection.
///</summary>
///
///<returns>
///An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.
///</returns>
///<filterpriority>2</filterpriority>
public IEnumerator GetEnumerator()
{
List<HttpInputItem> items = new List<HttpInputItem>(m_query);
items.AddRange(m_form);
return items.GetEnumerator();
}
#endregion
}
}

View File

@ -1,477 +0,0 @@
using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using OSHttpServer.Exceptions;
namespace OSHttpServer
{
/// <summary>
/// Contains server side HTTP request information.
/// </summary>
public class HttpRequest : IHttpRequest
{
/// <summary>
/// Chars used to split an URL path into multiple parts.
/// </summary>
public static readonly char[] UriSplitters = new[] { '/' };
public static uint baseID = 0;
private readonly NameValueCollection m_headers = new NameValueCollection();
private readonly HttpParam m_param = new HttpParam(HttpInput.Empty, HttpInput.Empty);
private Stream m_body = new MemoryStream();
private int m_bodyBytesLeft;
private ConnectionType m_connection = ConnectionType.KeepAlive;
private int m_contentLength;
private string m_httpVersion = string.Empty;
private string m_method = string.Empty;
private NameValueCollection m_queryString = null;
private Uri m_uri = null;
private string m_uriPath;
public readonly IHttpClientContext m_context;
IPEndPoint m_remoteIPEndPoint = null;
public HttpRequest(IHttpClientContext pContext)
{
ID = ++baseID;
m_context = pContext;
}
public uint ID { get; private set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="HttpRequest"/> is secure.
/// </summary>
public bool Secure { get { return m_context.IsSecured; } }
public IHttpClientContext Context { get { return m_context; } }
/// <summary>
/// Path and query (will be merged with the host header) and put in Uri
/// </summary>
/// <see cref="Uri"/>
public string UriPath
{
get { return m_uriPath; }
set { m_uriPath = value; }
}
/// <summary>
/// Assign a form.
/// </summary>
/// <param name="form"></param>
/*
internal void AssignForm(HttpForm form)
{
_form = form;
}
*/
#region IHttpRequest Members
/// <summary>
/// Gets kind of types accepted by the client.
/// </summary>
public string[] AcceptTypes { get; private set; }
/// <summary>
/// Gets or sets body stream.
/// </summary>
public Stream Body
{
get { return m_body; }
set { m_body = value; }
}
/// <summary>
/// Gets or sets kind of connection used for the session.
/// </summary>
public ConnectionType Connection
{
get { return m_connection; }
set { m_connection = value; }
}
/// <summary>
/// Gets or sets number of bytes in the body.
/// </summary>
public int ContentLength
{
get { return m_contentLength; }
set
{
m_contentLength = value;
m_bodyBytesLeft = value;
}
}
/// <summary>
/// Gets headers sent by the client.
/// </summary>
public NameValueCollection Headers
{
get { return m_headers; }
}
/// <summary>
/// Gets or sets version of HTTP protocol that's used.
/// </summary>
/// <remarks>
/// Probably <see cref="HttpHelper.HTTP10"/> or <see cref="HttpHelper.HTTP11"/>.
/// </remarks>
/// <seealso cref="HttpHelper"/>
public string HttpVersion
{
get { return m_httpVersion; }
set { m_httpVersion = value; }
}
/// <summary>
/// Gets or sets requested method.
/// </summary>
/// <value></value>
/// <remarks>
/// Will always be in upper case.
/// </remarks>
/// <see cref="OSHttpServer.Method"/>
public string Method
{
get { return m_method; }
set { m_method = value; }
}
/// <summary>
/// Gets variables sent in the query string
/// </summary>
public NameValueCollection QueryString
{
get
{
if(m_queryString == null)
{
if(m_uri == null || m_uri.Query.Length == 0)
m_queryString = new NameValueCollection();
else
{
try
{
m_queryString = HttpUtility.ParseQueryString(m_uri.Query);
}
catch { m_queryString = new NameValueCollection(); }
}
}
return m_queryString;
}
}
public static readonly Uri EmptyUri = new Uri("http://localhost/");
/// <summary>
/// Gets or sets requested URI.
/// </summary>
public Uri Uri
{
get { return m_uri; }
set { m_uri = value ?? EmptyUri; } // not safe
}
/// <summary>
/// Gets parameter from <see cref="QueryString"/> or <see cref="Form"/>.
/// </summary>
public HttpParam Param
{
get { return m_param; }
}
/// <summary>
/// Gets form parameters.
/// </summary>
/*
public HttpForm Form
{
get { return _form; }
}
*/
/// <summary>
/// Gets whether the request was made by Ajax (Asynchronous JavaScript)
/// </summary>
public bool IsAjax { get; private set; }
/// <summary>
/// Gets cookies that was sent with the request.
/// </summary>
public RequestCookies Cookies { get; private set; }
public double ArrivalTS { get; set;}
///<summary>
///Creates a new object that is a copy of the current instance.
///</summary>
///
///<returns>
///A new object that is a copy of this instance.
///</returns>
///<filterpriority>2</filterpriority>
public object Clone()
{
// this method was mainly created for testing.
// dont use it that much...
var request = new HttpRequest(Context);
request.Method = m_method;
if (AcceptTypes != null)
{
request.AcceptTypes = new string[AcceptTypes.Length];
AcceptTypes.CopyTo(request.AcceptTypes, 0);
}
request.m_httpVersion = m_httpVersion;
request.m_queryString = m_queryString;
request.Uri = m_uri;
var buffer = new byte[m_body.Length];
m_body.Read(buffer, 0, (int)m_body.Length);
request.Body = new MemoryStream();
request.Body.Write(buffer, 0, buffer.Length);
request.Body.Seek(0, SeekOrigin.Begin);
request.Body.Flush();
request.m_headers.Clear();
foreach (string key in m_headers)
{
string[] values = m_headers.GetValues(key);
if (values != null)
foreach (string value in values)
request.AddHeader(key, value);
}
return request;
}
/// <summary>
/// Decode body into a form.
/// </summary>
/// <param name="providers">A list with form decoders.</param>
/// <exception cref="InvalidDataException">If body contents is not valid for the chosen decoder.</exception>
/// <exception cref="InvalidOperationException">If body is still being transferred.</exception>
/*
public void DecodeBody(FormDecoderProvider providers)
{
if (_bodyBytesLeft > 0)
throw new InvalidOperationException("Body have not yet been completed.");
_form = providers.Decode(_headers["content-type"], _body, Encoding.UTF8);
if (_form != HttpInput.Empty)
_param.SetForm(_form);
}
*/
///<summary>
/// Cookies
///</summary>
///<param name="cookies">the cookies</param>
public void SetCookies(RequestCookies cookies)
{
Cookies = cookies;
}
public IPEndPoint LocalIPEndPoint { get {return m_context.LocalIPEndPoint; }}
public IPEndPoint RemoteIPEndPoint
{
get
{
if(m_remoteIPEndPoint == null)
{
string addr = m_headers["x-forwarded-for"];
if(!string.IsNullOrEmpty(addr))
{
int port = m_context.LocalIPEndPoint.Port;
try
{
m_remoteIPEndPoint = new IPEndPoint(IPAddress.Parse(addr), port);
}
catch
{
m_remoteIPEndPoint = null;
}
}
}
if (m_remoteIPEndPoint == null)
m_remoteIPEndPoint = m_context.LocalIPEndPoint;
return m_remoteIPEndPoint;
}
}
/*
/// <summary>
/// Create a response object.
/// </summary>
/// <returns>A new <see cref="IHttpResponse"/>.</returns>
public IHttpResponse CreateResponse(IHttpClientContext context)
{
return new HttpResponse(context, this);
}
*/
/// <summary>
/// Called during parsing of a <see cref="IHttpRequest"/>.
/// </summary>
/// <param name="name">Name of the header, should not be URL encoded</param>
/// <param name="value">Value of the header, should not be URL encoded</param>
/// <exception cref="BadRequestException">If a header is incorrect.</exception>
public void AddHeader(string name, string value)
{
if (string.IsNullOrEmpty(name))
throw new BadRequestException("Invalid header name: " + name ?? "<null>");
if (string.IsNullOrEmpty(value))
throw new BadRequestException("Header '" + name + "' do not contain a value.");
name = name.ToLowerInvariant();
switch (name)
{
case "http_x_requested_with":
case "x-requested-with":
if (string.Compare(value, "XMLHttpRequest", true) == 0)
IsAjax = true;
break;
case "accept":
AcceptTypes = value.Split(',');
for (int i = 0; i < AcceptTypes.Length; ++i)
AcceptTypes[i] = AcceptTypes[i].Trim();
break;
case "content-length":
if (!int.TryParse(value, out int t))
throw new BadRequestException("Invalid content length.");
ContentLength = t;
break; //todo: maybe throw an exception
case "host":
try
{
m_uri = new Uri((Secure ? "https://" : "http://") + value + m_uriPath);
m_uriPath = m_uri.AbsolutePath;
}
catch (UriFormatException err)
{
throw new BadRequestException("Failed to parse uri: " + value + m_uriPath, err);
}
break;
case "remote_addr":
if (m_headers[name] == null)
m_headers.Add(name, value);
break;
case "forwarded":
string[] parts = value.Split(new char[]{';'});
string addr = string.Empty;
for(int i = 0; i < parts.Length; ++i)
{
string s = parts[i].TrimStart();
if(s.Length < 10)
continue;
if(s.StartsWith("for", StringComparison.InvariantCultureIgnoreCase))
{
int indx = s.IndexOf("=", 3);
if(indx < 0 || indx >= s.Length - 1)
continue;
s = s.Substring(indx);
addr = s.Trim();
}
}
if(addr.Length > 7)
{
m_headers.Add("x-forwarded-for", addr);
}
break;
case "x-forwarded-for":
if (value.Length > 7)
{
string[] xparts = value.Split(new char[]{','});
if(xparts.Length > 0)
{
string xs = xparts[0].Trim();
if(xs.Length > 7)
m_headers.Add("x-forwarded-for", xs);
}
}
break;
case "connection":
if (string.Compare(value, "close", true) == 0)
Connection = ConnectionType.Close;
else if (value.StartsWith("keep-alive", StringComparison.CurrentCultureIgnoreCase))
Connection = ConnectionType.KeepAlive;
else if (value.StartsWith("Upgrade", StringComparison.CurrentCultureIgnoreCase))
Connection = ConnectionType.KeepAlive;
else
throw new BadRequestException("Unknown 'Connection' header type.");
break;
/*
case "expect":
if (value.Contains("100-continue"))
{
}
m_headers.Add(name, value);
break;
*/
case "user-agent":
break;
default:
m_headers.Add(name, value);
break;
}
}
/// <summary>
/// Add bytes to the body
/// </summary>
/// <param name="bytes">buffer to read bytes from</param>
/// <param name="offset">where to start read</param>
/// <param name="length">number of bytes to read</param>
/// <returns>Number of bytes actually read (same as length unless we got all body bytes).</returns>
/// <exception cref="InvalidOperationException">If body is not writable</exception>
/// <exception cref="ArgumentNullException"><c>bytes</c> is null.</exception>
/// <exception cref="ArgumentOutOfRangeException"><c>offset</c> is out of range.</exception>
public int AddToBody(byte[] bytes, int offset, int length)
{
if (bytes == null)
throw new ArgumentNullException("bytes");
if (offset + length > bytes.Length)
throw new ArgumentOutOfRangeException("offset");
if (length == 0)
return 0;
if (!m_body.CanWrite)
throw new InvalidOperationException("Body is not writable.");
if (length > m_bodyBytesLeft)
{
length = m_bodyBytesLeft;
}
m_body.Write(bytes, offset, length);
m_bodyBytesLeft -= length;
return length;
}
/// <summary>
/// Clear everything in the request
/// </summary>
public void Clear()
{
if (m_body != null && m_body.CanRead)
m_body.Dispose();
m_body = null;
m_contentLength = 0;
m_method = string.Empty;
m_uri = null;
m_queryString = null;
m_bodyBytesLeft = 0;
m_headers.Clear();
m_connection = ConnectionType.KeepAlive;
IsAjax = false;
//_form.Clear();
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More