Skip to content

Commit

Permalink
Bump version. Add code to LinksetData and LinksetEntry to do a deep c…
Browse files Browse the repository at this point in the history
…opy. We use that when doing a copy of prims because otherwise the dictionary ends being referenced from both prims on a shift copy, etc. Also used on a merge to create new entries. Fixed some of the accounting code which was incorrectly reporting usage and terminating a copy early on a merge.
  • Loading branch information
mdickson committed Dec 2, 2023
1 parent bfa2aa6 commit 3ae8a7b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 21 deletions.
2 changes: 1 addition & 1 deletion OpenSim/Framework/VersionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class VersionInfo
{
public const string VersionNumber = "0.9.2.2";
public const string AssemblyVersionNumber = "0.9.2.2";
public const string Release = "8729";
public const string Release = "8736";

public static string Version
{
Expand Down
62 changes: 44 additions & 18 deletions OpenSim/Region/Framework/Scenes/LinksetData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,33 @@ public LinksetData()
{
Data = new SortedList<string, LinksetDataEntry>();

LinksetDataBytesFree = 0;
LinksetDataBytesUsed = LINKSETDATA_MAX;
LinksetDataBytesFree = LINKSETDATA_MAX;
LinksetDataBytesUsed = 0;
}

public SortedList<string, LinksetDataEntry> Data { get; private set; } = null;

public int LinksetDataBytesFree { get; private set; } = LINKSETDATA_MAX;
public int LinksetDataBytesUsed { get; private set; } = 0;

// Deep Copy of Linkset Data
public LinksetData Copy()
{
lock (linksetDataLock)
{
var copy = new LinksetData();
foreach (var entry in Data)
{
var key = String.Copy(entry.Key);
var val = entry.Value.Copy();
copy.Data.Add(key, val);
copy.LinksetDataAccountingDelta(val.GetCost(key));
}

return copy;
}
}

/// <summary>
/// Adds or updates a entry to linkset data
/// </summary>
Expand Down Expand Up @@ -232,7 +250,7 @@ public string[] LinksetDataMultiDelete(string pattern, string pass, out int dele

public bool LinksetDataOverLimit()
{
return (LinksetDataBytesFree < 0);
return (LinksetDataBytesFree <= 0);
}

/// <summary>
Expand All @@ -259,15 +277,18 @@ public void MergeLinksetData(LinksetData otherLinksetData)
if (LinksetDataOverLimit())
break;

var value = new LinksetDataEntry(kvp.Value.Value, kvp.Value.Password);
Data.Add(kvp.Key, value);
LinksetDataAccountingDelta(value.GetCost(kvp.Key));
var key = string.Copy(kvp.Key);
var value = kvp.Value.Copy();

Data.Add(key, value);
LinksetDataAccountingDelta(value.GetCost(key));
}

// Clear the LinksetData entries from the "other" SOG
otherLinksetData.Data.Clear();
otherLinksetData.LinksetDataBytesFree = 0;
otherLinksetData.LinksetDataBytesUsed = LINKSETDATA_MAX;

otherLinksetData.LinksetDataBytesFree = LINKSETDATA_MAX;
otherLinksetData.LinksetDataBytesUsed = 0;
}
}

Expand Down Expand Up @@ -306,8 +327,8 @@ public void ResetLinksetData()

Data.Clear();

LinksetDataBytesFree = 0;
LinksetDataBytesUsed = LINKSETDATA_MAX;
LinksetDataBytesFree = LINKSETDATA_MAX;
LinksetDataBytesUsed = 0;
}
}

Expand All @@ -326,20 +347,19 @@ public string SerializeLinksetData()
private void LinksetDataAccountingDelta(int delta)
{
LinksetDataBytesUsed += delta;

if (LinksetDataBytesUsed < 0)
LinksetDataBytesUsed = 0;

LinksetDataBytesFree = LINKSETDATA_MAX - LinksetDataBytesUsed;

if (LinksetDataBytesFree < 0)
LinksetDataBytesFree = 0;
}
}

public class LinksetDataEntry
{
public LinksetDataEntry(string value, string password)
{
this.Value = value;
this.Password = password;
Value = value;
Password = password;
}

public string Password { get; private set; } = string.Empty;
Expand All @@ -350,12 +370,18 @@ public bool CheckPassword(string pass)
{
// A undocumented caveat for LinksetData appears to be that even for unprotected values,
// if a pass is provided, it is still treated as protected
return this.Password == pass ? true : false;
return string.IsNullOrEmpty(Password) || (Password == pass);
}

public string CheckPasswordAndGetValue(string pass)
{
return (string.IsNullOrEmpty(this.Password) || (this.Password == pass)) ? this.Value : string.Empty;
return CheckPassword(pass) ? Value : string.Empty;
}

// Deep Copy of Current Entry
public LinksetDataEntry Copy()
{
return new LinksetDataEntry(String.Copy(Value), Password ?? String.Copy(Password));

Check failure

Code scanning / CodeQL

Useless ?? expression Error

Both operands of this null-coalescing expression access the same variable or property.
}

/// <summary>
Expand Down
11 changes: 9 additions & 2 deletions OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2664,10 +2664,17 @@ public SceneObjectGroup Copy(bool userExposed)
public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
{
SceneObjectPart newpart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed);
// SceneObjectPart newpart = part.Copy(part.LocalId, OwnerID, GroupID, 0, userExposed);
// newpart.LocalId = m_scene.AllocateLocalId();
// SceneObjectPart newpart = part.Copy(part.LocalId, OwnerID, GroupID, 0, userExposed);
// newpart.LocalId = m_scene.AllocateLocalId();

// If the rootpart we're copying has LinksetData do a deep copy of that to the new rootpart.
if (part.LinksetData != null)
{
newpart.LinksetData = part.LinksetData.Copy();
}

SetRootPart(newpart);

if (userExposed)
RootPart.Velocity = Vector3.Zero; // In case source is moving
}
Expand Down

0 comments on commit 3ae8a7b

Please sign in to comment.