├── .dockerignore
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── github.autobuild.yml
├── .gitignore
├── BetterSecondBot.sln
├── Dockerfile
├── LICENSE
├── LibreMetaverse.StructuredData
├── JSON
│ ├── IJsonWrapper.cs
│ ├── JsonData.cs
│ ├── JsonException.cs
│ ├── JsonMapper.cs
│ ├── JsonReader.cs
│ ├── JsonWriter.cs
│ ├── Lexer.cs
│ ├── OSDJson.cs
│ └── ParserToken.cs
├── LLSD
│ ├── BinaryLLSD.cs
│ ├── NotationLLSD.cs
│ └── XmlLLSD.cs
├── LibreMetaverse.StructuredData.csproj
└── StructuredData.cs
├── LibreMetaverse.Types
├── CRC32.cs
├── CacheDictionary.cs
├── Color4.cs
├── DoubleDictionary.cs
├── Enums.cs
├── EnumsPrimitive.cs
├── ExpiringCache.cs
├── LibreMetaverse.Types.csproj
├── Matrix4.cs
├── MultiValueDictionary.cs
├── Quaternion.cs
├── Ray.cs
├── TokenBucket.cs
├── UUID.cs
├── Utils.cs
├── UtilsConversions.cs
├── Vector2.cs
├── Vector3.cs
├── Vector3d.cs
└── Vector4.cs
├── LibreMetaverse
├── AgentManager.cs
├── AgentManagerCamera.cs
├── AgentManagerMovement.cs
├── AgentThrottle.cs
├── Animations.cs
├── AppearanceManager.cs
├── AssetCache.cs
├── AssetManager.cs
├── Assets
│ ├── Archiving
│ │ ├── ArchiveConstants.cs
│ │ ├── AssetsArchiver.cs
│ │ ├── OarFile.cs
│ │ ├── RegionSettings.cs
│ │ ├── TarArchiveReader.cs
│ │ └── TarArchiveWriter.cs
│ ├── Asset.cs
│ └── AssetTypes
│ │ ├── AssetAnimation.cs
│ │ ├── AssetBodypart.cs
│ │ ├── AssetCallingCard.cs
│ │ ├── AssetClothing.cs
│ │ ├── AssetGesture.cs
│ │ ├── AssetLandmark.cs
│ │ ├── AssetMaterial.cs
│ │ ├── AssetMesh.cs
│ │ ├── AssetMutable.cs
│ │ ├── AssetNotecard.cs
│ │ ├── AssetPrim.cs
│ │ ├── AssetScriptBinary.cs
│ │ ├── AssetScriptText.cs
│ │ ├── AssetSettings.cs
│ │ ├── AssetSound.cs
│ │ ├── AssetTexture.cs
│ │ └── AssetWearable.cs
├── Avatar.cs
├── AvatarManager.cs
├── BVHDecoder.cs
├── BitPack.cs
├── Capabilities
│ ├── CapsBase.cs
│ ├── CapsClient.cs
│ ├── EventQueueClient.cs
│ └── HttpCapsClient.cs
├── Caps.cs
├── CapsToPacket.cs
├── CoordinateFrame.cs
├── DirectoryManager.cs
├── DownloadManager.cs
├── EstateTools.cs
├── EventDictionary.cs
├── Formatters
│ └── UUIDFormatter.cs
├── FriendsManager.cs
├── GridClient.cs
├── GridManager.cs
├── GroupManager.cs
├── Helpers.cs
├── Imaging
│ ├── BakeLayer.cs
│ ├── J2K.cs
│ ├── ManagedImage.cs
│ └── Targa.cs
├── ImportExport
│ ├── Collada.cs
│ ├── ColladalLoader.cs
│ ├── Model.cs
│ └── ModelUploader.cs
├── Interfaces
│ ├── IByteBufferPool.cs
│ ├── IMessage.cs
│ └── IRendering.cs
├── Inventory
│ ├── Inventory.cs
│ ├── InventoryAISClient.cs
│ ├── InventoryBase.cs
│ ├── InventoryCache.cs
│ ├── InventoryManager.cs
│ ├── InventoryNode.cs
│ └── InventoryNodeDictionary.cs
├── LibreMetaverse.csproj
├── LocationParser.cs
├── LockingDictionary.cs
├── Logger.cs
├── Login.cs
├── Materials
│ ├── LegacyMaterial.cs
│ └── LegacyMaterialAlphaMode.cs
├── Messages
│ ├── LindenMessages.cs
│ ├── MessageEventDecoder.cs
│ └── Messages.cs
├── NameValue.cs
├── NetworkManager.cs
├── ObjectManager.cs
├── ObservableDictionary.cs
├── PacketDecoder.cs
├── ParcelManager.cs
├── Permissions.cs
├── Primitives
│ ├── ObjectMedia.cs
│ ├── ParticleSystem.cs
│ ├── Primitive.cs
│ └── TextureEntry.cs
├── ProtocolManager.cs
├── Rendering
│ ├── EndianAwareBinaryReader.cs
│ ├── LindenMesh.cs
│ ├── LindenSkeleton.Ext.cs
│ ├── LindenSkeleton.Xsd.cs
│ └── Rendering.cs
├── Repeat.cs
├── Settings.cs
├── Simulator.cs
├── SoundManager.cs
├── Sounds.cs
├── TerrainCompressor.cs
├── TerrainManager.cs
├── TexturePipeline.cs
├── ThreadUtil.cs
├── Threading
│ ├── Disposers
│ │ ├── IAdvancedDisposable.cs
│ │ ├── IUpgradeableLock.cs
│ │ ├── OptimisticReadLock.cs
│ │ ├── OptimisticUpgradeableLock.cs
│ │ ├── OptimisticWriteLock.cs
│ │ ├── SpinReadLock.cs
│ │ ├── SpinUpgradeableLock.cs
│ │ └── SpinWriteLock.cs
│ ├── IEventWait.cs
│ ├── IReaderWriterLock.cs
│ ├── IReaderWriterLockSlim.cs
│ ├── ManagedAutoResetEvent.cs
│ ├── ManagedManualResetEvent.cs
│ ├── ManagedSemaphore.cs
│ ├── OptimisticReaderWriterLock.cs
│ ├── SpinLockSlim.cs
│ ├── SpinReaderWriterLock.cs
│ ├── SpinReaderWriterLockSlim.cs
│ └── WaitHandleAsyncFactory.cs
├── UDPBase.cs
├── UDPPacketBuffer.cs
├── UserReport.cs
├── UtilizationStatistics.cs
├── _Packets_.cs
└── _VisualParam_.cs
├── NuGet.Config
├── README.md
└── SecondBotEvents
├── Commands
├── Animation.cs
├── Avatars.cs
├── Chat.cs
├── Core.cs
├── Dialogs.cs
├── Discord.cs
├── Estate.cs
├── Friends.cs
├── Funds.cs
├── Group.cs
├── Info.cs
├── Inventory.cs
├── Movement.cs
├── Notecard.cs
├── ParcelCommands.cs
├── Self.cs
├── Services.cs
└── StreamAdmin.cs
├── Config
├── BasicConfig.cs
├── ChatGptConfig.cs
├── CommandsConfig.cs
├── CustomCommandsConfig.cs
├── DataStoreConfig.cs
├── DialogRelayConfig.cs
├── DiscordConfig.cs
├── EventsConfig.cs
├── HomeboundConfig.cs
├── HttpConfig.cs
├── InteractionConfig.cs
├── OnEventConfig.cs
├── RelayConfig.cs
├── RlvConfig.cs
├── SmtpConfig.cs
└── config.cs
├── EventsSecondBot.cs
├── Properties
├── Resources.Designer.cs
├── Resources.resx
└── launchSettings.json
├── RLV
├── RLVAttachmentInfo.cs
├── RLVEventArgs.cs
└── RLVRule.cs
├── SecondBotEvents.csproj
├── Services
├── BotClientService.cs
├── ChatGptService.cs
├── CommandsService.cs
├── CurrentOutfitFolder.cs
├── CustomCommandsService.cs
├── DataStoreService.cs
├── DialogService.cs
├── DiscordService.cs
├── EventsService.cs
├── HomeboundService.cs
├── HttpService.cs
├── InteractionService.cs
├── RLVService.cs
├── RecoveryService.cs
├── RelayService.cs
├── Services.cs
├── SmtpService.cs
└── TriggerOnEventService.cs
├── Static
├── Helpers.cs
├── Inventory.cs
├── LogFormater.cs
├── SimpleIO.cs
├── http_commands_helper.cs
├── parcel.cs
└── template.html
├── WikiService.cs
└── settings.env
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.classpath
2 | **/.dockerignore
3 | **/.env
4 | **/.gitignore
5 | **/.project
6 | **/.settings
7 | **/.toolstarget
8 | **/.vs
9 | **/.vscode
10 | **/*.*proj.user
11 | **/*.dbmdl
12 | **/*.jfm
13 | **/azds.yaml
14 | **/bin
15 | **/charts
16 | **/docker-compose*
17 | **/Dockerfile*
18 | **/node_modules
19 | **/npm-debug.log
20 | **/obj
21 | **/secrets.dev.yaml
22 | **/values.dev.yaml
23 | LICENSE
24 | README.md
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: Madpeterz
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Hardware (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Version [e.g. 22]
29 | - Running in docker: [Yes/No]
30 | - Running as linux service: [Yes/No]
31 |
32 | **Additional context**
33 | Add any other context about the problem here.
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: Madpeterz
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/github.autobuild.yml:
--------------------------------------------------------------------------------
1 | name: autobuild
2 |
3 | on:
4 | push:
5 |
6 | jobs:
7 | docker:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v4
12 | - name: Set up QEMU
13 | uses: docker/setup-qemu-action@v3
14 | - name: Set up Docker Buildx
15 | uses: docker/setup-buildx-action@v3
16 | - name: Login to Docker Hub
17 | uses: docker/login-action@v3
18 | with:
19 | username: ${{ secrets.DOCKERHUB_USERNAME }}
20 | password: ${{ secrets.DOCKERHUB_TOKEN }}
21 | - name: Build and push
22 | uses: docker/build-push-action@v6
23 | with:
24 | context: .
25 | push: true
26 | tags: madpeter/secondbot:events
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | compile.bat
2 | *.user
3 | *.userprefs
4 | *.suo
5 | *.cache
6 | *.pfx
7 | [Oo]bj/
8 | [Bb]in/
9 | packages/
10 | .idea/
11 | .vs/
12 | /Programs/examples/TestClient/Properties/launchSettings.json
13 | .appveyor.yml
14 | LICENSE.txt
15 | mapgen.bat
16 | PrimMesher/
17 | Programs/
18 | libremetaverse-core/.gitignore
19 | BetterSecondbot/Dockerfile
20 | BetterSecondbot/wiki/
21 | BetterSecondbot/debug.json
22 | SecondBotEvents/defaultBot/
23 |
--------------------------------------------------------------------------------
/LibreMetaverse.StructuredData/JSON/IJsonWrapper.cs:
--------------------------------------------------------------------------------
1 | #region Header
2 | /*
3 | * IJsonWrapper.cs
4 | * Interface that represents a type capable of handling all kinds of JSON
5 | * data. This is mainly used when mapping objects through JsonMapper, and
6 | * it's implemented by JsonData.
7 | *
8 | * The authors disclaim copyright to this source code. For more details, see
9 | * the COPYING file included with this distribution.
10 | */
11 | #endregion
12 |
13 |
14 | using System.Collections;
15 | using System.Collections.Specialized;
16 |
17 |
18 | namespace LitJson
19 | {
20 | public enum JsonType
21 | {
22 | None,
23 |
24 | Object,
25 | Array,
26 | String,
27 | Int,
28 | Long,
29 | Double,
30 | Boolean
31 | }
32 |
33 | public interface IJsonWrapper : IList, IOrderedDictionary
34 | {
35 | bool IsArray { get; }
36 | bool IsBoolean { get; }
37 | bool IsDouble { get; }
38 | bool IsInt { get; }
39 | bool IsLong { get; }
40 | bool IsObject { get; }
41 | bool IsString { get; }
42 |
43 | bool GetBoolean ();
44 | double GetDouble ();
45 | int GetInt ();
46 | JsonType GetJsonType ();
47 | long GetLong ();
48 | string GetString ();
49 |
50 | void SetBoolean (bool val);
51 | void SetDouble (double val);
52 | void SetInt (int val);
53 | void SetJsonType (JsonType jtype);
54 | void SetLong (long val);
55 | void SetString (string val);
56 |
57 | string ToJson ();
58 | void ToJson (JsonWriter writer);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/LibreMetaverse.StructuredData/JSON/JsonException.cs:
--------------------------------------------------------------------------------
1 | #region Header
2 | /*
3 | * JsonException.cs
4 | * Base class throwed by LitJSON when a parsing error occurs.
5 | *
6 | * The authors disclaim copyright to this source code. For more details, see
7 | * the COPYING file included with this distribution.
8 | */
9 | #endregion
10 |
11 |
12 | using System;
13 |
14 |
15 | namespace LitJson
16 | {
17 | [Serializable]
18 | public class JsonException : ApplicationException
19 | {
20 | public JsonException ()
21 | {
22 | }
23 |
24 | internal JsonException (ParserToken token) :
25 | base ($"Invalid token '{token}' in input string")
26 | {
27 | }
28 |
29 | internal JsonException (ParserToken token,
30 | Exception inner_exception) :
31 | base ($"Invalid token '{token}' in input string",
32 | inner_exception)
33 | {
34 | }
35 |
36 | internal JsonException (int c) :
37 | base ($"Invalid character '{(char) c}' in input string")
38 | {
39 | }
40 |
41 | internal JsonException (int c, Exception inner_exception) :
42 | base ($"Invalid character '{(char) c}' in input string",
43 | inner_exception)
44 | {
45 | }
46 |
47 |
48 | public JsonException (string message) : base (message)
49 | {
50 | }
51 |
52 | public JsonException (string message, Exception inner_exception) :
53 | base (message, inner_exception)
54 | {
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/LibreMetaverse.StructuredData/JSON/ParserToken.cs:
--------------------------------------------------------------------------------
1 | #region Header
2 | /*
3 | * ParserToken.cs
4 | * Internal representation of the tokens used by the lexer and the parser.
5 | *
6 | * The authors disclaim copyright to this source code. For more details, see
7 | * the COPYING file included with this distribution.
8 | */
9 | #endregion
10 |
11 |
12 | namespace LitJson
13 | {
14 | internal enum ParserToken
15 | {
16 | // Lexer tokens
17 | None = char.MaxValue + 1,
18 | Number,
19 | True,
20 | False,
21 | Null,
22 | CharSeq,
23 | // Single char
24 | Char,
25 |
26 | // Parser Rules
27 | Text,
28 | Object,
29 | ObjectPrime,
30 | Pair,
31 | PairRest,
32 | Array,
33 | ArrayPrime,
34 | Value,
35 | ValueRest,
36 | String,
37 |
38 | // End of input
39 | End,
40 |
41 | // The empty rule
42 | Epsilon
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/LibreMetaverse.StructuredData/LibreMetaverse.StructuredData.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | LibreMetaverse.StructuredData
4 | LibreMetaverse structured data library
5 | LibreMetaverse.StructuredData
6 | netstandard2.0;net8.0;net9.0
7 | Library
8 | LibreMetaverse.StructuredData
9 | true
10 | true
11 | snupkg
12 | $(NoWarn);CS0419;CS1591;CS1574
13 | AnyCPU
14 | ..\bin\
15 |
16 |
17 | TRACE;DEBUG
18 | False
19 |
20 |
21 | true
22 | pdbonly
23 | TRACE
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LibreMetaverse.Types/LibreMetaverse.Types.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | LibreMetaverse.Types
4 | LibreMetaverse.Types
5 | LibreMetaverse type library
6 | netstandard2.0;net8.0;net9.0
7 | Library
8 | LibreMetaverse
9 | true
10 | true
11 | snupkg
12 | $(NoWarn);CS0419;CS1591;CS1574
13 | AnyCPU
14 | ..\bin\
15 |
16 |
17 | TRACE;DEBUG
18 | False
19 |
20 |
21 | true
22 | pdbonly
23 | TRACE
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/LibreMetaverse.Types/Ray.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse
28 | {
29 | public struct Ray
30 | {
31 | public Vector3 Origin;
32 | public Vector3 Direction;
33 |
34 | public Ray(Vector3 origin, Vector3 direction)
35 | {
36 | Origin = origin;
37 | Direction = direction;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/Asset.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Base class for all Asset types
31 | ///
32 | public abstract class Asset
33 | {
34 | /// A byte array containing the raw asset data
35 | public byte[] AssetData;
36 | /// True if the asset it only stored on the server temporarily
37 | public bool Temporary;
38 |
39 | /// The assets unique ID
40 | public UUID AssetID { get; internal set; }
41 |
42 | ///
43 | /// The "type" of asset, Notecard, Animation, etc
44 | ///
45 | public abstract AssetType AssetType
46 | {
47 | get;
48 | }
49 |
50 | ///
51 | /// Construct a new Asset object
52 | ///
53 | protected Asset() { }
54 |
55 | ///
56 | /// Construct a new Asset object
57 | ///
58 | /// A unique specific to this asset
59 | /// A byte array containing the raw asset data
60 | protected Asset(UUID assetID, byte[] assetData)
61 | {
62 | AssetID = assetID;
63 | AssetData = assetData;
64 | }
65 |
66 | ///
67 | /// Regenerates the > byte array from the properties
68 | /// of the derived class.
69 | ///
70 | public abstract void Encode();
71 |
72 | ///
73 | /// Decodes the AssetData, placing it in appropriate properties of the derived
74 | /// class.
75 | ///
76 | /// True if the asset decoding succeeded, otherwise false
77 | public abstract bool Decode();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetAnimation.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Represents an Animation
31 | ///
32 | public class AssetAnimation : Asset
33 | {
34 | /// Override the base classes AssetType
35 | public override AssetType AssetType => AssetType.Animation;
36 |
37 | /// Default Constructor
38 | public AssetAnimation() { }
39 |
40 | ///
41 | /// Construct an Asset object of type Animation
42 | ///
43 | /// A unique specific to this asset
44 | /// A byte array containing the raw asset data
45 | public AssetAnimation(UUID assetID, byte[] assetData)
46 | : base(assetID, assetData)
47 | {
48 | }
49 |
50 | public sealed override void Encode() { }
51 | public sealed override bool Decode() { return true; }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetBodypart.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Represents an that represents an avatars body ie: Hair, Etc.
31 | ///
32 | public class AssetBodypart : AssetWearable
33 | {
34 | /// Override the base classes AssetType
35 | public override AssetType AssetType => AssetType.Bodypart;
36 |
37 | /// Initializes a new instance of an AssetBodyPart object
38 | public AssetBodypart() { }
39 |
40 | /// Initializes a new instance of an AssetBodyPart object with parameters
41 | /// A unique specific to this asset
42 | /// A byte array containing the raw asset data
43 | public AssetBodypart(UUID assetID, byte[] assetData) : base(assetID, assetData) { }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetCallingCard.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace OpenMetaverse.Assets
30 | {
31 | ///
32 | /// Represents a Callingcard with AvatarID and Position vector
33 | ///
34 | public class AssetCallingCard : Asset
35 | {
36 | /// Override the base classes AssetType
37 | public override AssetType AssetType => AssetType.CallingCard;
38 |
39 | /// UUID of the Callingcard target avatar
40 | public UUID AvatarID = UUID.Zero;
41 |
42 | /// Construct an Asset of type Callingcard
43 | public AssetCallingCard() { }
44 |
45 | ///
46 | /// Construct an Asset object of type Callingcard
47 | ///
48 | /// A unique specific to this asset
49 | /// A byte array containing the raw asset data
50 | public AssetCallingCard(UUID assetID, byte[] assetData)
51 | : base(assetID, assetData)
52 | {
53 | Decode();
54 | }
55 |
56 | ///
57 | /// Constuct an asset of type Callingcard
58 | ///
59 | /// UUID of the target avatar
60 | public AssetCallingCard(UUID avatarID)
61 | {
62 | AvatarID = avatarID;
63 | Encode();
64 | }
65 |
66 | ///
67 | /// Encode the raw contents of a string with the specific Callingcard format
68 | ///
69 | public sealed override void Encode()
70 | {
71 | string temp = "Callingcard version 2\n";
72 | temp += "avatar_id " + AvatarID + "\n";
73 | AssetData = Utils.StringToBytes(temp);
74 | }
75 |
76 | ///
77 | /// Decode the raw asset data, populating the AvatarID and Position
78 | ///
79 | /// true if the AssetData was successfully decoded to a UUID and Vector
80 | public sealed override bool Decode()
81 | {
82 | String text = Utils.BytesToString(AssetData);
83 | if (text.ToLower().Contains("callingcard version 2"))
84 | {
85 | AvatarID = new UUID(text.Substring(text.IndexOf("avatar_id", StringComparison.Ordinal) + 10, 36));
86 | return true;
87 | }
88 | return false;
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetClothing.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Represents an that can be worn on an avatar
31 | /// such as a Shirt, Pants, etc.
32 | ///
33 | public class AssetClothing : AssetWearable
34 | {
35 | /// Override the base classes AssetType
36 | public override AssetType AssetType => AssetType.Clothing;
37 |
38 | /// Initializes a new instance of an AssetScriptBinary object
39 | public AssetClothing() { }
40 |
41 | /// Initializes a new instance of an AssetScriptBinary object with parameters
42 | /// A unique specific to this asset
43 | /// A byte array containing the raw asset data
44 | public AssetClothing(UUID assetID, byte[] assetData) : base(assetID, assetData) { }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetLandmark.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace OpenMetaverse.Assets
30 | {
31 | ///
32 | /// Represents a Landmark with RegionID and Position vector
33 | ///
34 | public class AssetLandmark : Asset
35 | {
36 | /// Override the base classes AssetType
37 | public override AssetType AssetType => AssetType.Landmark;
38 |
39 | /// UUID of the Landmark target region
40 | public UUID RegionID = UUID.Zero;
41 | /// Local position of the target
42 | public Vector3 Position = Vector3.Zero;
43 |
44 | /// Construct an Asset of type Landmark
45 | public AssetLandmark() { }
46 |
47 | ///
48 | /// Construct an Asset object of type Landmark
49 | ///
50 | /// A unique specific to this asset
51 | /// A byte array containing the raw asset data
52 | public AssetLandmark(UUID assetID, byte[] assetData)
53 | : base(assetID, assetData)
54 | {
55 | }
56 |
57 | ///
58 | /// Encode the raw contents of a string with the specific Landmark format
59 | ///
60 | public sealed override void Encode()
61 | {
62 | string temp = "Landmark version 2\n";
63 | temp += "region_id " + RegionID + "\n";
64 | temp += string.Format(Utils.EnUsCulture, "local_pos {0:0.00} {1:0.00} {2:0.00}\n", Position.X, Position.Y, Position.Z);
65 | AssetData = Utils.StringToBytes(temp);
66 | }
67 |
68 | ///
69 | /// Decode the raw asset data, populating the RegionID and Position
70 | ///
71 | /// true if the AssetData was successfully decoded to a UUID and Vector
72 | public sealed override bool Decode()
73 | {
74 | string text = Utils.BytesToString(AssetData);
75 | if (text.ToLower().Contains("landmark version 2"))
76 | {
77 | RegionID = new UUID(text.Substring(text.IndexOf("region_id", StringComparison.Ordinal) + 10, 36));
78 | const string vecDelim = " ";
79 | string[] vecStrings = text.Substring(text.IndexOf("local_pos", StringComparison.Ordinal) + 10).Split(vecDelim.ToCharArray());
80 | if (vecStrings.Length == 3)
81 | {
82 | Position = new Vector3(float.Parse(vecStrings[0], System.Globalization.CultureInfo.InvariantCulture), float.Parse(vecStrings[1], System.Globalization.CultureInfo.InvariantCulture), float.Parse(vecStrings[2], System.Globalization.CultureInfo.InvariantCulture));
83 | return true;
84 | }
85 | }
86 | return false;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetMaterial.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | public class AssetMaterial : Asset
30 | {
31 | public override AssetType AssetType => AssetType.Material;
32 |
33 | /// Initializes a new instance of an AssetMaterial object
34 | public AssetMaterial() { }
35 |
36 | ///
37 | /// Construct an Asset object of type Material
38 | ///
39 | /// A unique specific to this asset
40 | /// A byte array containing the raw asset data
41 | public AssetMaterial(UUID assetId, byte[] assetData)
42 | : base(assetId, assetData)
43 | {
44 | Decode();
45 | }
46 |
47 | public override void Encode()
48 | {
49 | throw new System.NotImplementedException();
50 | }
51 |
52 | public sealed override bool Decode()
53 | {
54 | throw new System.NotImplementedException();
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetMesh.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.IO;
29 | using OpenMetaverse.StructuredData;
30 |
31 | namespace OpenMetaverse.Assets
32 | {
33 | ///
34 | /// Represents Mesh asset
35 | ///
36 | public class AssetMesh : Asset
37 | {
38 | /// Override the base classes AssetType
39 | public override AssetType AssetType => AssetType.Mesh;
40 |
41 | ///
42 | /// Decoded mesh data
43 | ///
44 | public OSDMap MeshData;
45 |
46 | /// Initializes a new instance of an AssetMesh object
47 | public AssetMesh() { }
48 |
49 | /// Initializes a new instance of an AssetMesh object with parameters
50 | /// A unique specific to this asset
51 | /// A byte array containing the raw asset data
52 | public AssetMesh(UUID assetID, byte[] assetData)
53 | : base(assetID, assetData)
54 | {
55 | }
56 |
57 | ///
58 | /// TODO: Encodes Collada file into LLMesh format
59 | ///
60 | public sealed override void Encode() { }
61 |
62 | ///
63 | /// Decodes mesh asset. See
64 | /// to furter decode it for rendering
65 | /// true
66 | public sealed override bool Decode()
67 | {
68 | try
69 | {
70 | MeshData = new OSDMap();
71 |
72 | using (MemoryStream data = new MemoryStream(AssetData))
73 | {
74 | OSDMap header = (OSDMap)OSDParser.DeserializeLLSDBinary(data);
75 | MeshData["asset_header"] = header;
76 | long start = data.Position;
77 |
78 | foreach(string partName in header.Keys)
79 | {
80 | if (header[partName].Type != OSDType.Map)
81 | {
82 | MeshData[partName] = header[partName];
83 | continue;
84 | }
85 |
86 | OSDMap partInfo = (OSDMap)header[partName];
87 | if (partInfo["offset"] < 0 || partInfo["size"] == 0)
88 | {
89 | MeshData[partName] = partInfo;
90 | continue;
91 | }
92 |
93 | byte[] part = new byte[partInfo["size"]];
94 | Buffer.BlockCopy(AssetData, partInfo["offset"] + (int)start, part, 0, part.Length);
95 | MeshData[partName] = Helpers.DecompressOSD(part);
96 | }
97 | }
98 | return true;
99 | }
100 | catch (Exception ex)
101 | {
102 | Logger.Log("Failed to decode mesh asset", Helpers.LogLevel.Error, ex);
103 | return false;
104 | }
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetMutable.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Represents an Animation
31 | ///
32 | public class AssetMutable : Asset
33 | {
34 | public AssetType currentType;
35 |
36 | /// Override the base classes AssetType
37 | public override AssetType AssetType => currentType;
38 |
39 | /// Default Constructor
40 | public AssetMutable(AssetType type)
41 | {
42 | currentType = type;
43 | }
44 |
45 | ///
46 | /// Construct an Asset object of type Animation
47 | ///
48 | /// Asset type
49 | /// A unique specific to this asset
50 | /// A byte array containing the raw asset data
51 | public AssetMutable(AssetType type, UUID assetID, byte[] assetData)
52 | : base(assetID, assetData)
53 | {
54 | currentType = type;
55 | }
56 |
57 | public override void Encode() { }
58 | public override bool Decode() { return true; }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetScriptBinary.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Represents an AssetScriptBinary object containing the
31 | /// LSO compiled bytecode of an LSL script
32 | ///
33 | public class AssetScriptBinary : Asset
34 | {
35 | /// Override the base classes AssetType
36 | public override AssetType AssetType => AssetType.LSLBytecode;
37 |
38 | /// Initializes a new instance of an AssetScriptBinary object
39 | public AssetScriptBinary() { }
40 |
41 | /// Initializes a new instance of an AssetScriptBinary object with parameters
42 | /// A unique specific to this asset
43 | /// A byte array containing the raw asset data
44 | public AssetScriptBinary(UUID assetID, byte[] assetData)
45 | : base(assetID, assetData)
46 | {
47 | }
48 |
49 | ///
50 | /// TODO: Encodes a scripts contents into a LSO Bytecode file
51 | ///
52 | public sealed override void Encode() { }
53 |
54 | ///
55 | /// TODO: Decode LSO Bytecode into a string
56 | ///
57 | /// true
58 | public sealed override bool Decode() { return true; }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetScriptText.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace OpenMetaverse.Assets
28 | {
29 | ///
30 | /// Represents an LSL Text object containing a string of UTF encoded characters
31 | ///
32 | public class AssetScriptText : Asset
33 | {
34 | /// Override the base classes AssetType
35 | public override AssetType AssetType => AssetType.LSLText;
36 |
37 | /// A string of characters represting the script contents
38 | public string Source;
39 |
40 | /// Initializes a new AssetScriptText object
41 | public AssetScriptText() { }
42 |
43 | ///
44 | /// Initializes a new AssetScriptText object with parameters
45 | ///
46 | /// A unique specific to this asset
47 | /// A byte array containing the raw asset data
48 | public AssetScriptText(UUID assetID, byte[] assetData) : base(assetID, assetData) { }
49 |
50 | ///
51 | /// Encode a string containing the scripts contents into byte encoded AssetData
52 | ///
53 | public sealed override void Encode()
54 | {
55 | AssetData = Utils.StringToBytes(Source);
56 | }
57 |
58 | ///
59 | /// Decode a byte array containing the scripts contents into a string
60 | ///
61 | /// true if decoding is successful
62 | public sealed override bool Decode()
63 | {
64 | Source = Utils.BytesToString(AssetData);
65 | return true;
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetSettings.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using OpenMetaverse.StructuredData;
28 |
29 | namespace OpenMetaverse.Assets
30 | {
31 | public class AssetSettings : Asset
32 | {
33 | public override AssetType AssetType => AssetType.Settings;
34 |
35 | public OSD Settings;
36 |
37 | /// Initializes a new instance of an AssetSettings object
38 | public AssetSettings() { }
39 |
40 | ///
41 | /// Construct an Asset object of type Settings
42 | ///
43 | /// A unique specific to this asset
44 | /// A byte array containing the raw asset data
45 | public AssetSettings(UUID assetId, byte[] assetData)
46 | : base(assetId, assetData)
47 | {
48 | Decode();
49 | }
50 |
51 | public override void Encode()
52 | {
53 | AssetData = Utils.StringToBytes(Settings.AsString());
54 | }
55 |
56 | public sealed override bool Decode()
57 | {
58 | if (AssetData != null && AssetData.Length > 0)
59 | {
60 | try
61 | {
62 | var raw = Utils.BytesToString(AssetData);
63 | Settings = OSD.FromString(raw);
64 | return true;
65 | }
66 | catch
67 | {
68 | return false;
69 | }
70 | }
71 |
72 | return false;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/LibreMetaverse/Assets/AssetTypes/AssetTexture.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * Copyright (c) 2021-2024, Sjofn LLC.
4 | * All rights reserved.
5 | *
6 | * - Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * - Redistributions of source code must retain the above copyright notice, this
10 | * list of conditions and the following disclaimer.
11 | * - Neither the name of the openmetaverse.co nor the names
12 | * of its contributors may be used to endorse or promote products derived from
13 | * this software without specific prior written permission.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 | * POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | using CoreJ2K;
29 | using OpenMetaverse.Imaging;
30 |
31 | namespace OpenMetaverse.Assets
32 | {
33 | ///
34 | /// Represents a texture
35 | ///
36 | public class AssetTexture : Asset
37 | {
38 | /// Override the base classes AssetType
39 | public override AssetType AssetType => AssetType.Texture;
40 |
41 | /// A object containing image data
42 | public ManagedImage Image;
43 |
44 | ///
45 | public int Components;
46 |
47 | /// Initializes a new instance of an AssetTexture object
48 | public AssetTexture() { }
49 |
50 | ///
51 | /// Initializes a new instance of an AssetTexture object
52 | ///
53 | /// A unique specific to this asset
54 | /// A byte array containing the raw asset data
55 | public AssetTexture(UUID assetID, byte[] assetData) : base(assetID, assetData) { }
56 |
57 | ///
58 | /// Initializes a new instance of an AssetTexture object
59 | ///
60 | /// A object containing texture data
61 | public AssetTexture(ManagedImage image)
62 | {
63 | Image = image;
64 | Components = 0;
65 | if ((Image.Channels & ManagedImage.ImageChannels.Color) != 0)
66 | Components += 3;
67 | if ((Image.Channels & ManagedImage.ImageChannels.Gray) != 0)
68 | ++Components;
69 | if ((Image.Channels & ManagedImage.ImageChannels.Bump) != 0)
70 | ++Components;
71 | if ((Image.Channels & ManagedImage.ImageChannels.Alpha) != 0)
72 | ++Components;
73 | }
74 |
75 | ///
76 | /// Populates the byte array with a JPEG2000
77 | /// encoded image created from the data in
78 | ///
79 | public sealed override void Encode()
80 | {
81 | AssetData = J2K.ToBytes(Image.ExportBitmap());
82 | }
83 |
84 | ///
85 | /// Decodes the JPEG2000 data in > to the
86 | /// object
87 | ///
88 | /// True if the decoding was successful, otherwise false
89 | public sealed override bool Decode()
90 | {
91 | if (AssetData == null || AssetData.Length <= 0) { return false; }
92 |
93 | this.Components = 0;
94 |
95 | var image = J2kImage.FromBytes(AssetData);
96 | Image = new ManagedImage(image);
97 |
98 | if ((Image.Channels & ManagedImage.ImageChannels.Color) != 0)
99 | Components += 3;
100 | if ((Image.Channels & ManagedImage.ImageChannels.Gray) != 0)
101 | ++Components;
102 | if ((Image.Channels & ManagedImage.ImageChannels.Bump) != 0)
103 | ++Components;
104 | if ((Image.Channels & ManagedImage.ImageChannels.Alpha) != 0)
105 | ++Components;
106 |
107 | return true;
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/LibreMetaverse/Formatters/UUIDFormatter.cs:
--------------------------------------------------------------------------------
1 | using MessagePack;
2 | using MessagePack.Formatters;
3 | using System;
4 | using System.Buffers;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace OpenMetaverse.Formatters
9 | {
10 | public class UUIDFormatter : IMessagePackFormatter
11 | {
12 | public static readonly UUIDFormatter Instance = new UUIDFormatter();
13 |
14 | public void Serialize(ref MessagePackWriter writer, UUID value, MessagePackSerializerOptions options)
15 | {
16 | writer.Write(value.GetBytes());
17 | }
18 |
19 | public UUID Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
20 | {
21 | var sequence = reader.ReadBytes();
22 | if (sequence == null)
23 | {
24 | throw new MessagePackSerializationException("Invalid UUID");
25 | }
26 |
27 | var bytes = sequence.Value.ToArray();
28 | return new UUID(bytes, 0);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LibreMetaverse/Interfaces/IByteBufferPool.cs:
--------------------------------------------------------------------------------
1 | namespace OpenMetaverse.Interfaces
2 | {
3 | ///
4 | /// Interface to a class that can supply cached byte arrays
5 | ///
6 | public interface IByteBufferPool
7 | {
8 | ///
9 | /// Leases a byte array from the pool
10 | ///
11 | /// Minimum size the array must be to satisfy this request
12 | /// A poooled array that is at least minSize
13 | byte[] LeaseBytes(int minSize);
14 |
15 | ///
16 | /// Returns a byte array to the pool
17 | ///
18 | /// The bytes being returned
19 | void ReturnBytes(byte[] bytes);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/LibreMetaverse/Interfaces/IMessage.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using OpenMetaverse.StructuredData;
28 |
29 |
30 | namespace OpenMetaverse.Interfaces
31 | {
32 | ///
33 | /// Interface requirements for Messaging system
34 | ///
35 | public interface IMessage
36 | {
37 | OSDMap Serialize();
38 | void Deserialize(OSDMap map);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LibreMetaverse/Interfaces/IRendering.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using SkiaSharp;
30 |
31 | namespace OpenMetaverse.Rendering
32 | {
33 | [AttributeUsage(AttributeTargets.Class)]
34 | public class RendererNameAttribute : System.Attribute
35 | {
36 | private string _name;
37 |
38 | public RendererNameAttribute(string name)
39 | {
40 | _name = name;
41 | }
42 |
43 | public override string ToString()
44 | {
45 | return _name;
46 | }
47 | }
48 |
49 | ///
50 | /// Abstract base for rendering plugins
51 | ///
52 | public interface IRendering
53 | {
54 | ///
55 | /// Generates a basic mesh structure from a primitive
56 | ///
57 | /// Primitive to generate the mesh from
58 | /// Level of detail to generate the mesh at
59 | /// The generated mesh
60 | SimpleMesh GenerateSimpleMesh(Primitive prim, DetailLevel lod);
61 |
62 | ///
63 | /// Generates a basic mesh structure from a sculpted primitive and
64 | /// texture
65 | ///
66 | /// Sculpted primitive to generate the mesh from
67 | /// Sculpt texture
68 | /// Level of detail to generate the mesh at
69 | /// The generated mesh
70 | SimpleMesh GenerateSimpleSculptMesh(Primitive prim, SKBitmap sculptTexture, DetailLevel lod);
71 |
72 | ///
73 | /// Generates a series of faces, each face containing a mesh and
74 | /// metadata
75 | ///
76 | /// Primitive to generate the mesh from
77 | /// Level of detail to generate the mesh at
78 | /// The generated mesh
79 | FacetedMesh GenerateFacetedMesh(Primitive prim, DetailLevel lod);
80 |
81 | ///
82 | /// Generates a series of faces for a sculpted prim, each face
83 | /// containing a mesh and metadata
84 | ///
85 | /// Sculpted primitive to generate the mesh from
86 | /// Sculpt texture
87 | /// Level of detail to generate the mesh at
88 | /// The generated mesh
89 | FacetedMesh GenerateFacetedSculptMesh(Primitive prim, SKBitmap sculptTexture, DetailLevel lod);
90 |
91 | ///
92 | /// Apply texture coordinate modifications from a
93 | /// to a list of vertices
94 | ///
95 | /// Vertex list to modify texture coordinates for
96 | /// Center-point of the face
97 | /// Face texture parameters
98 | /// Scale of the prim
99 | void TransformTexCoords (List vertices, Vector3 center, Primitive.TextureEntryFace teFace, Vector3 primScale);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/LibreMetaverse/Inventory/InventoryNode.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * Copyright (c) 2021-2024, Sjofn LLC.
4 | * All rights reserved.
5 | *
6 | * - Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * - Redistributions of source code must retain the above copyright notice, this
10 | * list of conditions and the following disclaimer.
11 | * - Neither the name of the openmetaverse.co nor the names
12 | * of its contributors may be used to endorse or promote products derived from
13 | * this software without specific prior written permission.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 | * POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | using System;
29 | using MessagePack;
30 |
31 | namespace OpenMetaverse
32 | {
33 | [MessagePackObject]
34 | public partial class InventoryNode
35 | {
36 | private InventoryNodeDictionary nodes;
37 |
38 | [Key("Data")]
39 | public InventoryBase Data { get; set; }
40 |
41 | /// User data
42 | [IgnoreMember]
43 | public object Tag { get; set; }
44 |
45 | [IgnoreMember]
46 | public InventoryNode Parent { get; set; }
47 |
48 | [IgnoreMember]
49 | public InventoryNodeDictionary Nodes
50 | {
51 | get => nodes ?? (nodes = new InventoryNodeDictionary(this));
52 | set => nodes = value;
53 | }
54 |
55 | ///
56 | /// For inventory folder nodes specifies weather the folder needs to be
57 | /// refreshed from the server
58 | ///
59 | [IgnoreMember]
60 | public bool NeedsUpdate { get; set; } = true;
61 |
62 | [IgnoreMember]
63 | public DateTime ModifyTime
64 | {
65 | get
66 | {
67 | if (Data is InventoryItem item)
68 | {
69 | return item.CreationDate;
70 | }
71 | DateTime newest = default(DateTime); //.MinValue;
72 | if (Data is InventoryFolder)
73 | {
74 | foreach (var node in Nodes.Values)
75 | {
76 | var t = node.ModifyTime;
77 | if (t > newest) newest = t;
78 | }
79 | }
80 | return newest;
81 | }
82 | }
83 |
84 | public void Sort()
85 | {
86 | Nodes.Sort();
87 | }
88 |
89 | public InventoryNode()
90 | {
91 | }
92 |
93 | ///
94 | public InventoryNode(InventoryBase data)
95 | {
96 | this.Data = data;
97 | }
98 |
99 | ///
100 | /// De-serialization constructor for the InventoryNode Class
101 | ///
102 | public InventoryNode(InventoryBase data, InventoryNode parent)
103 | {
104 | this.Data = data;
105 | this.Parent = parent;
106 |
107 | if (parent != null)
108 | {
109 | // Add this node to the collection of parent nodes
110 | lock (parent.Nodes.SyncRoot) parent.Nodes.Add(data.UUID, this);
111 | }
112 | }
113 |
114 | public override string ToString()
115 | {
116 | return this.Data == null ? "[Empty Node]" : this.Data.ToString();
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/LibreMetaverse/LibreMetaverse.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | LibreMetaverse
4 | LibreMetaverse
5 | LibreMetaverse allows your code to read and work with data send across a SecondLife, Halcyon, OpenSimulator, or related connection.
6 | Library
7 | LibreMetaverse
8 | true
9 | true
10 | true
11 | true
12 | true
13 | snupkg
14 | $(NoWarn);CS0419;CS8981;CS1591;CS1574
15 | netstandard2.0;net8.0;net9.0
16 | AnyCPU
17 | ..\bin\
18 |
19 |
20 | TRACE;DEBUG
21 |
22 |
23 | true
24 | pdbonly
25 | TRACE
26 | True
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/LibreMetaverse/LocationParser.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Sjofn, LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace OpenMetaverse
30 | {
31 | public class LocationParser
32 | {
33 | public string Sim { get; }
34 | public int X { get; }
35 | public int Y { get; }
36 | public int Z { get; }
37 |
38 | public LocationParser(string location)
39 | {
40 | if (location == null ) { throw new ArgumentNullException(nameof(location), "Location cannot be null."); }
41 | if (location.Length == 0) { throw new ArgumentException("Location cannot be empty."); }
42 |
43 | string toParse;
44 | if (location.StartsWith("secondlife://")) { toParse = location.Substring(13); }
45 | else if (location.StartsWith("uri:")) { toParse = location.Substring(4); }
46 | else { toParse = location; }
47 |
48 | string[] elements = toParse.Split('/');
49 | Sim = elements[0];
50 | int parsed;
51 | X = (elements.Length > 1 && int.TryParse(elements[1], out parsed)) ? parsed : 128;
52 | Y = (elements.Length > 2 && int.TryParse(elements[2], out parsed)) ? parsed : 128;
53 | Z = (elements.Length > 3 && int.TryParse(elements[3], out parsed)) ? parsed : 0;
54 | }
55 |
56 | public string GetRawLocation()
57 | {
58 | return $"{Sim}/{X}/{Y}/{Z}";
59 | }
60 |
61 | public string GetSlurl()
62 | {
63 | return $"secondlife://{Sim}/{X}/{Y}/{Z}/";
64 | }
65 |
66 | public string GetStartLocationUri()
67 | {
68 | return $"uri:{Sim}&{X}&{Y}&{Z}";
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/LibreMetaverse/Materials/LegacyMaterial.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using OpenMetaverse;
4 | using OpenMetaverse.StructuredData;
5 |
6 | namespace LibreMetaverse.Materials
7 | {
8 | public class LegacyMaterial
9 | {
10 | public UUID ID { get; set; }
11 |
12 | public UUID NormalMap { get; set; }
13 | public double NormalMapOffsetX { get; set; }
14 | public double NormalMapOffsetY { get; set; }
15 | public double NormalMapRepeatX { get; set; }
16 | public double NormalMapRepeatY { get; set; }
17 | public double NormalMapRotation { get; set; }
18 |
19 | public UUID SpecularMap { get; set; }
20 | public double SpecularMapOffsetX { get; set; }
21 | public double SpecularMapOffsetY { get; set; }
22 | public double SpecularMapRepeatX { get; set; }
23 | public double SpecularMapRepeatY { get; set; }
24 | public double SpecularMapRotation { get; set; }
25 |
26 | public Color4 SpecularColor { get; set; }
27 | public byte SpecularExponent { get; set; }
28 | public byte EnvironmentIntensity { get; set; }
29 | public byte AlphaMaskCutoff { get; set; }
30 |
31 | public LegacyMaterialAlphaMode DiffuseAlphaMode { get; set; }
32 |
33 | public LegacyMaterial()
34 | {
35 |
36 | }
37 |
38 | private const double MaterialsMultiplier = 10000.0;
39 |
40 | public LegacyMaterial(OSDMap mapOrig)
41 | {
42 | if (!(mapOrig.ContainsKey("ID") && mapOrig.ContainsKey("Material")))
43 | {
44 | throw new InvalidOperationException("Legacy material needs to contain 'ID' and 'Material' keys.");
45 | }
46 |
47 | if (mapOrig["ID"] is OSDBinary idBinary)
48 | {
49 | ID = new UUID(idBinary.AsBinary(), 0);
50 | }
51 | else if (mapOrig["ID"] is OSDArray idArray)
52 | {
53 | ID = new UUID(idArray.AsBinary(), 0);
54 | }
55 | else if (mapOrig["ID"] is OSDUUID idUUID)
56 | {
57 | ID = idUUID.AsUUID();
58 | }
59 | else
60 | {
61 | throw new InvalidOperationException("LegacyMaterial ID is of an unknown type " + mapOrig["ID"].Type);
62 | }
63 |
64 | if (mapOrig["Material"] is OSDMap map)
65 | {
66 | NormalMap = map["NormMap"].AsUUID();
67 | NormalMapOffsetX = map["NormOffsetX"].AsInteger() / MaterialsMultiplier;
68 | NormalMapOffsetY = map["NormOffsetY"].AsInteger() / MaterialsMultiplier;
69 | NormalMapRepeatX = map["NormRepeatX"].AsInteger() / MaterialsMultiplier;
70 | NormalMapRepeatY = map["NormRepeatX"].AsInteger() / MaterialsMultiplier;
71 | NormalMapRotation = map["NormRotation"].AsInteger() / MaterialsMultiplier;
72 |
73 | SpecularMap = map["NormMap"].AsUUID();
74 | SpecularMapOffsetX = map["NormOffsetX"].AsInteger() / MaterialsMultiplier;
75 | SpecularMapOffsetY = map["NormOffsetY"].AsInteger() / MaterialsMultiplier;
76 | SpecularMapRepeatX = map["NormRepeatX"].AsInteger() / MaterialsMultiplier;
77 | SpecularMapRepeatY = map["NormRepeatX"].AsInteger() / MaterialsMultiplier;
78 | SpecularMapRotation = map["NormRotation"].AsInteger() / MaterialsMultiplier;
79 |
80 | SpecularColor = map["SpecColor"].AsColor4();
81 | SpecularExponent = (byte)map["SpecExp"].AsInteger();
82 | EnvironmentIntensity = (byte)map["EnvIntensity"].AsInteger();
83 | AlphaMaskCutoff = (byte)map["AlphaMaskCutoff"].AsInteger();
84 | DiffuseAlphaMode = (LegacyMaterialAlphaMode)map["DiffuseAlphaMode"].AsInteger();
85 | }
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/LibreMetaverse/Materials/LegacyMaterialAlphaMode.cs:
--------------------------------------------------------------------------------
1 | namespace LibreMetaverse.Materials
2 | {
3 | public enum LegacyMaterialAlphaMode : byte
4 | {
5 | None = 0,
6 | Blend = 1,
7 | Mask = 2,
8 | Emissive = 3,
9 | Default = 4,
10 | }
11 | }
--------------------------------------------------------------------------------
/LibreMetaverse/Messages/Messages.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Net;
30 | using OpenMetaverse.StructuredData;
31 |
32 | namespace OpenMetaverse.Messages
33 | {
34 | public static partial class MessageUtils
35 | {
36 | public static IPAddress ToIP(OSD osd)
37 | {
38 | byte[] binary = osd.AsBinary();
39 | if (binary != null && binary.Length == 4)
40 | return new IPAddress(binary);
41 | else
42 | return IPAddress.Any;
43 | }
44 |
45 | public static OSD FromIP(IPAddress address)
46 | {
47 | if (address != null && !Equals(address, IPAddress.Any))
48 | return OSD.FromBinary(address.GetAddressBytes());
49 | else
50 | return new OSD();
51 | }
52 |
53 | public static Dictionary ToDictionaryString(OSD osd)
54 | {
55 | if (osd.Type == OSDType.Map)
56 | {
57 | OSDMap map = (OSDMap)osd;
58 | Dictionary dict = new Dictionary(map.Count);
59 | foreach (KeyValuePair entry in map)
60 | dict.Add(entry.Key, entry.Value.AsString());
61 | return dict;
62 | }
63 |
64 | return new Dictionary(0);
65 | }
66 |
67 | public static Dictionary ToDictionaryUri(OSD osd)
68 | {
69 | if (osd.Type == OSDType.Map)
70 | {
71 | OSDMap map = (OSDMap)osd;
72 | Dictionary dict = new Dictionary(map.Count);
73 | foreach (KeyValuePair entry in map)
74 | dict.Add(new Uri(entry.Key), entry.Value.AsUri());
75 | return dict;
76 | }
77 |
78 | return new Dictionary(0);
79 | }
80 |
81 | public static OSDMap FromDictionaryString(Dictionary dict)
82 | {
83 | if (dict != null)
84 | {
85 | OSDMap map = new OSDMap(dict.Count);
86 | foreach (KeyValuePair entry in dict)
87 | map.Add(entry.Key, OSD.FromString(entry.Value));
88 | return map;
89 | }
90 |
91 | return new OSDMap(0);
92 | }
93 |
94 | public static OSDMap FromDictionaryUri(Dictionary dict)
95 | {
96 | if (dict != null)
97 | {
98 | OSDMap map = new OSDMap(dict.Count);
99 | foreach (KeyValuePair entry in dict)
100 | map.Add(entry.Key.ToString(), OSD.FromUri(entry.Value));
101 | return map;
102 | }
103 |
104 | return new OSDMap(0);
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/LibreMetaverse/Repeat.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, Sjofn LLC.
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.Threading.Tasks;
29 | using System.Threading;
30 |
31 | namespace LibreMetaverse
32 | {
33 | internal static class Repeat
34 | {
35 | ///
36 | /// Execute a given at a given interval in a loop
37 | ///
38 | /// Interval for executing action
39 | /// Essentially the action you wish to execute
40 | /// Cancellation token
41 | /// When set, executes the action immediately instead of waiting for the interval
42 | ///
43 | public static Task Interval(
44 | TimeSpan pollInterval,
45 | Action action,
46 | CancellationToken token,
47 | bool immediately = false)
48 | {
49 | return Task.Factory.StartNew(
50 | () =>
51 | {
52 | if (immediately) { action(); }
53 |
54 | for (; ; )
55 | {
56 | if (token.WaitCancellationRequested(pollInterval)) { break; }
57 | action();
58 | }
59 | }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
60 | }
61 |
62 | ///
63 | /// Execute a given at a given interval in a loop
64 | ///
65 | /// Interval for executing action
66 | /// Essentially the action you wish to execute
67 | /// Cancellation token
68 | /// When set, executes the action immediately instead of waiting for the interval
69 | ///
70 | public static Task IntervalAsync(
71 | TimeSpan pollInterval,
72 | Func asyncAction,
73 | CancellationToken token,
74 | bool immediately = false)
75 | {
76 | return Task.Factory.StartNew(
77 | async () =>
78 | {
79 | if (immediately)
80 | {
81 | await asyncAction(); }
82 |
83 | for (; ; )
84 | {
85 | if (token.WaitCancellationRequested(pollInterval)) { break; }
86 | await asyncAction();
87 | }
88 | }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
89 | }
90 | }
91 |
92 | internal static class CancellationTokenExtensions
93 | {
94 | public static bool WaitCancellationRequested(
95 | this CancellationToken token,
96 | TimeSpan timeout)
97 | {
98 | return token.WaitHandle.WaitOne(timeout);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/LibreMetaverse/ThreadUtil.cs:
--------------------------------------------------------------------------------
1 | // Written by Peter A. Bromberg, found at
2 | // http://www.eggheadcafe.com/articles/20060727.asp
3 |
4 | using System;
5 |
6 | ///
7 | ///
8 | ///
9 | public class ThreadUtil
10 | {
11 | ///
12 | /// Delegate to wrap another delegate and its arguments
13 | ///
14 | ///
15 | ///
16 | delegate void DelegateWrapper(Delegate d, object[] args);
17 |
18 | ///
19 | /// An instance of DelegateWrapper which calls InvokeWrappedDelegate,
20 | /// which in turn calls the DynamicInvoke method of the wrapped
21 | /// delegate
22 | ///
23 | static readonly DelegateWrapper wrapperInstance = InvokeWrappedDelegate;
24 |
25 | ///
26 | /// Callback used to call EndInvoke on the asynchronously
27 | /// invoked DelegateWrapper
28 | ///
29 | static readonly AsyncCallback callback = EndWrapperInvoke;
30 |
31 | ///
32 | /// Executes the specified delegate with the specified arguments
33 | /// asynchronously on a thread pool thread
34 | ///
35 | ///
36 | ///
37 | public static void FireAndForget(Delegate d, params object[] args)
38 | {
39 | // Invoke the wrapper asynchronously, which will then
40 | // execute the wrapped delegate synchronously (in the
41 | // thread pool thread)
42 | if (d != null) wrapperInstance.BeginInvoke(d, args, callback, null);
43 | }
44 |
45 | ///
46 | /// Invokes the wrapped delegate synchronously
47 | ///
48 | ///
49 | ///
50 | private static void InvokeWrappedDelegate(Delegate d, object[] args)
51 | {
52 | d.DynamicInvoke(args);
53 | }
54 |
55 | ///
56 | /// Calls EndInvoke on the wrapper and Close on the resulting WaitHandle
57 | /// to prevent resource leaks
58 | ///
59 | ///
60 | public static void EndWrapperInvoke(IAsyncResult ar)
61 | {
62 | wrapperInstance.EndInvoke(ar);
63 | ar.AsyncWaitHandle.Close();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/IAdvancedDisposable.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Interface for disposable objects that can inform they are already
33 | /// disposed without throwing an exception.
34 | ///
35 | public interface IAdvancedDisposable:
36 | IDisposable
37 | {
38 | ///
39 | /// Gets a value indicating if the object was already disposed.
40 | ///
41 | bool WasDisposed { get; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/IUpgradeableLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Interface implemented by ReaderWriterLocks' result to the
33 | /// UpgradeableLock method.
34 | ///
35 | public interface IUpgradeableLock:
36 | IDisposable
37 | {
38 | ///
39 | /// Upgrades this lock to a write-lock, returning an object
40 | /// so you can return to the upgradeable lock mode.
41 | ///
42 | IDisposable DisposableUpgrade();
43 |
44 | ///
45 | /// Upgrades this lock to an write lock, but it is
46 | /// not possible to return to the upgradeable lock any more.
47 | /// At the end, both the upgradeable and the write-lock
48 | /// will be released.
49 | ///
50 | bool Upgrade();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/OptimisticReadLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Class returned by ReadLock method.
33 | ///
34 | public struct OptimisticReadLock:
35 | IDisposable
36 | {
37 | private OptimisticReaderWriterLock _lock;
38 | internal OptimisticReadLock(OptimisticReaderWriterLock yieldLock)
39 | {
40 | _lock = yieldLock;
41 | }
42 |
43 | ///
44 | /// Releases the lock.
45 | ///
46 | public void Dispose()
47 | {
48 | var yieldLock = _lock;
49 |
50 | if (yieldLock != null)
51 | {
52 | _lock = null;
53 | yieldLock.ExitReadLock();
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/OptimisticUpgradeableLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Class returned by UpgradeableLock method.
33 | ///
34 | public struct OptimisticUpgradeableLock:
35 | IUpgradeableLock
36 | {
37 | private OptimisticReaderWriterLock _lock;
38 | private bool _upgraded;
39 |
40 | internal OptimisticUpgradeableLock(OptimisticReaderWriterLock yieldLock)
41 | {
42 | _lock = yieldLock;
43 | _upgraded = false;
44 | }
45 |
46 | ///
47 | /// Upgrades this lock to a write-lock.
48 | ///
49 | public OptimisticWriteLock DisposableUpgrade()
50 | {
51 | var yieldLock = _lock;
52 | if (yieldLock == null)
53 | throw new ObjectDisposedException(GetType().FullName);
54 |
55 | yieldLock.UncheckedUpgradeToWriteLock();
56 | return new OptimisticWriteLock(yieldLock);
57 | }
58 |
59 | ///
60 | /// Upgrades the lock to a write-lock.
61 | /// Returns true if the lock was upgraded, false if it was
62 | /// already upgraded before.
63 | ///
64 | public bool Upgrade()
65 | {
66 | var yieldLock = _lock;
67 | if (yieldLock == null)
68 | throw new ObjectDisposedException(GetType().FullName);
69 |
70 | if (_upgraded)
71 | return false;
72 |
73 | yieldLock.UncheckedUpgradeToWriteLock();
74 | _upgraded = true;
75 | return true;
76 | }
77 |
78 | ///
79 | /// Releases the lock.
80 | ///
81 | public void Dispose()
82 | {
83 | var yieldLock = _lock;
84 |
85 | if (yieldLock != null)
86 | {
87 | _lock = null;
88 |
89 | yieldLock.ExitUpgradeableLock(_upgraded);
90 | }
91 | }
92 |
93 | IDisposable IUpgradeableLock.DisposableUpgrade()
94 | {
95 | return DisposableUpgrade();
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/OptimisticWriteLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Class returned by WriteLock method.
33 | ///
34 | public struct OptimisticWriteLock:
35 | IDisposable
36 | {
37 | private OptimisticReaderWriterLock _lock;
38 | internal OptimisticWriteLock(OptimisticReaderWriterLock yieldLock)
39 | {
40 | _lock = yieldLock;
41 | }
42 |
43 | ///
44 | /// Releases the lock.
45 | ///
46 | public void Dispose()
47 | {
48 | var yieldLock = _lock;
49 |
50 | if (yieldLock != null)
51 | {
52 | _lock = null;
53 | yieldLock.ExitWriteLock();
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/SpinReadLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Class returned by ReadLock method.
33 | ///
34 | public struct SpinReadLock:
35 | IDisposable
36 | {
37 | private SpinReaderWriterLock _lock;
38 | internal SpinReadLock(SpinReaderWriterLock yieldLock)
39 | {
40 | _lock = yieldLock;
41 | }
42 |
43 | ///
44 | /// Releases the lock.
45 | ///
46 | public void Dispose()
47 | {
48 | var yieldLock = _lock;
49 |
50 | if (yieldLock != null)
51 | {
52 | _lock = null;
53 | yieldLock.Lock.ExitReadLock();
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/SpinUpgradeableLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Class returned by UpgradeableLock method.
33 | ///
34 | public struct SpinUpgradeableLock:
35 | IUpgradeableLock
36 | {
37 | private SpinReaderWriterLock _lock;
38 | private bool _upgraded;
39 |
40 | internal SpinUpgradeableLock(SpinReaderWriterLock yieldLock)
41 | {
42 | _lock = yieldLock;
43 | _upgraded = false;
44 | }
45 |
46 | ///
47 | /// Upgrades this lock to a write-lock.
48 | ///
49 | public SpinWriteLock DisposableUpgrade()
50 | {
51 | var yieldLock = _lock;
52 | if (yieldLock == null)
53 | throw new ObjectDisposedException(GetType().FullName);
54 |
55 | yieldLock.Lock.UncheckedUpgradeToWriteLock();
56 | return new SpinWriteLock(yieldLock);
57 | }
58 |
59 | ///
60 | /// Upgrades the lock to a write-lock.
61 | /// Returns true if the lock was upgraded, false if it was
62 | /// already upgraded before.
63 | ///
64 | public bool Upgrade()
65 | {
66 | var yieldLock = _lock;
67 | if (yieldLock == null)
68 | throw new ObjectDisposedException(GetType().FullName);
69 |
70 | if (_upgraded)
71 | return false;
72 |
73 | yieldLock.Lock.UncheckedUpgradeToWriteLock();
74 | _upgraded = true;
75 | return true;
76 | }
77 |
78 | ///
79 | /// Releases the lock.
80 | ///
81 | public void Dispose()
82 | {
83 | var yieldLock = _lock;
84 |
85 | if (yieldLock != null)
86 | {
87 | _lock = null;
88 |
89 | yieldLock.Lock.ExitUpgradeableLock(_upgraded);
90 | }
91 | }
92 |
93 | IDisposable IUpgradeableLock.DisposableUpgrade()
94 | {
95 | return DisposableUpgrade();
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/Disposers/SpinWriteLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading.Disposers
30 | {
31 | ///
32 | /// Class returned by WriteLock method.
33 | ///
34 | public struct SpinWriteLock:
35 | IDisposable
36 | {
37 | private SpinReaderWriterLock _lock;
38 | internal SpinWriteLock(SpinReaderWriterLock yieldLock)
39 | {
40 | _lock = yieldLock;
41 | }
42 |
43 | ///
44 | /// Releases the lock.
45 | ///
46 | public void Dispose()
47 | {
48 | var yieldLock = _lock;
49 |
50 | if (yieldLock != null)
51 | {
52 | _lock = null;
53 | yieldLock.Lock.ExitWriteLock();
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/IEventWait.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 |
29 | namespace LibreMetaverse.Threading
30 | {
31 | ///
32 | /// Interface implemented by PooledEventWait. And, thanks to StructuralCaster, can be used to
33 | /// access custom EventWait objects.
34 | ///
35 | public interface IEventWait:
36 | IDisposable
37 | {
38 | ///
39 | /// Waits for this event to be signalled.
40 | ///
41 | void WaitOne();
42 |
43 | ///
44 | /// Waits for this event to be signalled or times-out.
45 | /// Returns if the object was signalled.
46 | ///
47 | bool WaitOne(int millisecondsTimeout);
48 |
49 | ///
50 | /// Waits for this event to be signalled or times-out.
51 | /// Returns if the object was signalled.
52 | ///
53 | bool WaitOne(TimeSpan timeout);
54 |
55 | ///
56 | /// Resets (unsignals) this wait event.
57 | ///
58 | void Reset();
59 |
60 | ///
61 | /// Sets (signals) this wait event.
62 | ///
63 | void Set();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/IReaderWriterLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using LibreMetaverse.Threading.Disposers;
29 |
30 | namespace LibreMetaverse.Threading
31 | {
32 | ///
33 | /// Defines the contract that ReaderWriterLocks must follow.
34 | /// Note that if you want an Enter/Exit pair, you should
35 | /// use the IReaderWriterLockSlim.
36 | ///
37 | public interface IReaderWriterLock
38 | {
39 | ///
40 | /// Obtains a read lock. You should use it in a using clause
41 | /// so at the end the lock is released.
42 | ///
43 | IDisposable ReadLock();
44 |
45 | ///
46 | /// Obtains an upgradeable lock. You can use the returned
47 | /// value to upgrade the lock. Also, you should dispose
48 | /// the returned object (an using block is preferreable) to
49 | /// release the lock.
50 | ///
51 | IUpgradeableLock UpgradeableLock();
52 |
53 | ///
54 | /// Obtains an write lock. Call this method in a using clause
55 | /// so the lock is released at the end.
56 | ///
57 | IDisposable WriteLock();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/IReaderWriterLockSlim.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | namespace LibreMetaverse.Threading
28 | {
29 | ///
30 | /// Interface that must be implemented by reader-writer lock
31 | /// classes that are "slim". That is, they have Enter/Exit
32 | /// methods instead of returning disposable instances (which
33 | /// makes them faster, but more error prone).
34 | ///
35 | public interface IReaderWriterLockSlim
36 | {
37 | ///
38 | /// Enters a read lock. Many readers can enter
39 | /// the read lock at the same time.
40 | ///
41 | void EnterReadLock();
42 |
43 | ///
44 | /// Exits a previously entered read lock.
45 | ///
46 | void ExitReadLock();
47 |
48 | ///
49 | /// Enters an upgradeable read lock. Many read locks can
50 | /// be obtained at the same time that a single upgradeable
51 | /// read lock is active, but two upgradeable or an
52 | /// upgradeable and an write lock are not permitted.
53 | ///
54 | void EnterUpgradeableLock();
55 |
56 | ///
57 | /// Exits a previously entered upgradeable read lock.
58 | /// You should pass the boolean telling if the lock was
59 | /// upgraded or not.
60 | ///
61 | ///
62 | void ExitUpgradeableLock(bool upgraded);
63 |
64 | ///
65 | /// Exits an upgradeable read lock, considering it was never
66 | /// upgraded.
67 | ///
68 | void UncheckedExitUpgradeableLock();
69 |
70 | ///
71 | /// Upgraded a previously obtained upgradeable lock to a write
72 | /// lock, but does not check if the lock was already upgraded.
73 | ///
74 | void UncheckedUpgradeToWriteLock();
75 |
76 | ///
77 | /// Upgraded the upgradeable lock to a write lock, checking if
78 | /// it was already upgraded or not (and also updating the upgraded
79 | /// boolean). To upgrade, the lock will wait all readers to end.
80 | ///
81 | void UpgradeToWriteLock(ref bool upgraded);
82 |
83 | ///
84 | /// Exits an upgradeable lock that was also upgraded in a single
85 | /// task.
86 | ///
87 | void UncheckedExitUpgradedLock();
88 |
89 | ///
90 | /// Enters a write lock. That is, the lock will only be obtained when
91 | /// there are no readers, be them upgradeable or not.
92 | ///
93 | void EnterWriteLock();
94 |
95 | ///
96 | /// Exits a previously obtained write lock.
97 | ///
98 | void ExitWriteLock();
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/ManagedAutoResetEvent.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.Threading;
29 | using LibreMetaverse.Threading.Disposers;
30 |
31 | namespace LibreMetaverse.Threading
32 | {
33 | ///
34 | /// An auto reset event that uses only Monitor methods to work, avoiding
35 | /// operating system events.
36 | ///
37 | public sealed class ManagedAutoResetEvent:
38 | IAdvancedDisposable,
39 | IEventWait
40 | {
41 | private readonly object _lock = new object();
42 | private bool _value;
43 | private bool _wasDisposed;
44 |
45 | ///
46 | /// Creates a new event, not signaled.
47 | ///
48 | public ManagedAutoResetEvent()
49 | {
50 | }
51 |
52 | ///
53 | /// Creates a new event, letting you say if it starts signaled or not.
54 | ///
55 | public ManagedAutoResetEvent(bool initialState)
56 | {
57 | _value = initialState;
58 | }
59 |
60 | ///
61 | /// Disposes this event. After disposing, it is always set.
62 | /// Calling Reset will not work and it will not throw exceptions, so you can
63 | /// dispose it when there are threads waiting on it.
64 | ///
65 | public void Dispose()
66 | {
67 | lock(_lock)
68 | {
69 | _wasDisposed = true;
70 | _value = true;
71 | Monitor.PulseAll(_lock);
72 | }
73 | }
74 |
75 | ///
76 | /// Gets a value indicating if this event was disposed.
77 | ///
78 | public bool WasDisposed => _wasDisposed;
79 |
80 | ///
81 | /// Gets a value indicating if this auto-reset event is set.
82 | ///
83 | public bool IsSet => _value;
84 |
85 | ///
86 | /// Resets this event (makes it non-signaled).
87 | ///
88 | public void Reset()
89 | {
90 | lock(_lock)
91 | {
92 | if (_wasDisposed)
93 | return;
94 |
95 | _value = false;
96 | }
97 | }
98 |
99 | ///
100 | /// Signals the event, releasing one thread waiting on it.
101 | ///
102 | public void Set()
103 | {
104 | lock(_lock)
105 | {
106 | _value = true;
107 | Monitor.Pulse(_lock);
108 | }
109 | }
110 |
111 | ///
112 | /// Waits until this event is signaled.
113 | ///
114 | public void WaitOne()
115 | {
116 | lock(_lock)
117 | {
118 | while(!_value)
119 | Monitor.Wait(_lock);
120 |
121 | if (!_wasDisposed)
122 | _value = false;
123 | }
124 | }
125 |
126 | ///
127 | /// Waits until this event is signaled or until the timeout arrives.
128 | /// Return of true means it was signaled, false means timeout.
129 | ///
130 | public bool WaitOne(int millisecondsTimeout)
131 | {
132 | lock(_lock)
133 | {
134 | while(!_value)
135 | if (!Monitor.Wait(_lock, millisecondsTimeout))
136 | return false;
137 |
138 | if (!_wasDisposed)
139 | _value = false;
140 | }
141 |
142 | return true;
143 | }
144 |
145 | ///
146 | /// Waits until this event is signaled or until the timeout arrives.
147 | /// Return of true means it was signaled, false means timeout.
148 | ///
149 | public bool WaitOne(TimeSpan timeout)
150 | {
151 | lock(_lock)
152 | {
153 | while(!_value)
154 | if (!Monitor.Wait(_lock, timeout))
155 | return false;
156 |
157 | if (!_wasDisposed)
158 | _value = false;
159 | }
160 |
161 | return true;
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/ManagedManualResetEvent.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.Threading;
29 | using LibreMetaverse.Threading.Disposers;
30 |
31 | namespace LibreMetaverse.Threading
32 | {
33 | ///
34 | /// A manual reset event that uses only Monitor methods to work, avoiding
35 | /// operating system events.
36 | ///
37 | public sealed class ManagedManualResetEvent:
38 | IAdvancedDisposable,
39 | IEventWait
40 | {
41 | private readonly object _lock = new object();
42 | private bool _value;
43 | private bool _wasDisposed;
44 |
45 | ///
46 | /// Creates a new event, not signaled.
47 | ///
48 | public ManagedManualResetEvent()
49 | {
50 | }
51 |
52 | ///
53 | /// Creates a new event, letting you say if it starts signaled or not.
54 | ///
55 | public ManagedManualResetEvent(bool initialState)
56 | {
57 | _value = initialState;
58 | }
59 |
60 | ///
61 | /// Disposes this event. After disposing, it is always set.
62 | /// Calling Reset will not work and it will not throw exceptions, so you can
63 | /// dispose it when there are threads waiting on it.
64 | ///
65 | public void Dispose()
66 | {
67 | lock(_lock)
68 | {
69 | _wasDisposed = true;
70 | _value = true;
71 | Monitor.PulseAll(_lock);
72 | }
73 | }
74 |
75 | ///
76 | /// Gets a value indicating if this event was disposed.
77 | ///
78 | public bool WasDisposed => _wasDisposed;
79 |
80 | ///
81 | /// Gets a value indicating if this auto-reset event is set.
82 | ///
83 | public bool IsSet => _value;
84 |
85 | ///
86 | /// Resets this event (makes it non-signaled).
87 | ///
88 | public void Reset()
89 | {
90 | lock(_lock)
91 | {
92 | if (_wasDisposed)
93 | return;
94 |
95 | _value = false;
96 | }
97 | }
98 |
99 | ///
100 | /// Signals the event, releasing any threads waiting on it.
101 | ///
102 | public void Set()
103 | {
104 | lock(_lock)
105 | {
106 | _value = true;
107 | Monitor.PulseAll(_lock);
108 | }
109 | }
110 |
111 | ///
112 | /// Waits until this event is signaled.
113 | ///
114 | public void WaitOne()
115 | {
116 | lock(_lock)
117 | {
118 | while(!_value)
119 | Monitor.Wait(_lock);
120 | }
121 | }
122 |
123 | ///
124 | /// Waits until this event is signaled or until the timeout arrives.
125 | /// Return of true means it was signaled, false means timeout.
126 | ///
127 | public bool WaitOne(int millisecondsTimeout)
128 | {
129 | lock(_lock)
130 | {
131 | while(!_value)
132 | if (!Monitor.Wait(_lock, millisecondsTimeout))
133 | return false;
134 | }
135 |
136 | return true;
137 | }
138 |
139 | ///
140 | /// Waits until this event is signaled or until the timeout arrives.
141 | /// Return of true means it was signaled, false means timeout.
142 | ///
143 | public bool WaitOne(TimeSpan timeout)
144 | {
145 | lock(_lock)
146 | {
147 | while(!_value)
148 | if (!Monitor.Wait(_lock, timeout))
149 | return false;
150 | }
151 |
152 | return true;
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/ManagedSemaphore.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using System.Threading;
29 | using LibreMetaverse.Threading.Disposers;
30 |
31 | namespace LibreMetaverse.Threading
32 | {
33 | ///
34 | /// A semaphore class that uses only Monitor class for synchronization, avoiding
35 | /// operating system events.
36 | ///
37 | public sealed class ManagedSemaphore:
38 | IAdvancedDisposable
39 | {
40 | private readonly object _lock = new object();
41 | private int _availableCount;
42 |
43 | ///
44 | /// Creates a new semaphore with the given availableCount.
45 | ///
46 | public ManagedSemaphore(int availableCount)
47 | {
48 | if (availableCount < 1)
49 | throw new ArgumentException("availableCount must be at least 1.", nameof(availableCount));
50 |
51 | _availableCount = availableCount;
52 | }
53 |
54 | ///
55 | /// Disposes this semaphore.
56 | /// If you try to enter or exit it after this, the action will always return immediately.
57 | ///
58 | public void Dispose()
59 | {
60 | lock(_lock)
61 | {
62 | _availableCount = -1;
63 | Monitor.PulseAll(_lock);
64 | }
65 | }
66 |
67 | ///
68 | /// Gets a value indicating if this semaphore was disposed.
69 | ///
70 | public bool WasDisposed => _availableCount == -1;
71 |
72 | ///
73 | /// Enters the actual semaphore.
74 | ///
75 | public void Enter()
76 | {
77 | lock(_lock)
78 | {
79 | while(true)
80 | {
81 | if (_availableCount == -1)
82 | return;
83 |
84 | if (_availableCount > 0)
85 | {
86 | _availableCount--;
87 | return;
88 | }
89 |
90 | Monitor.Wait(_lock);
91 | }
92 | }
93 | }
94 |
95 | ///
96 | /// Enters the actual semaphore with the given count value.
97 | /// If you pass a value higher than the one used to create it, you will dead-lock (at least until
98 | /// the semaphore is disposed).
99 | ///
100 | public void Enter(int count)
101 | {
102 | if (count <= 0)
103 | throw new ArgumentException("count of semaphores to enter must be at least 1.", nameof(count));
104 |
105 | lock(_lock)
106 | {
107 | while(true)
108 | {
109 | if (_availableCount == -1)
110 | return;
111 |
112 | if (_availableCount >= count)
113 | {
114 | _availableCount -= count;
115 | return;
116 | }
117 |
118 | Monitor.Wait(_lock);
119 | }
120 | }
121 | }
122 |
123 | ///
124 | /// Exits the semaphore. One thread can enter it and another one exit it. There is no check for that.
125 | ///
126 | public void Exit()
127 | {
128 | lock(_lock)
129 | {
130 | if (_availableCount == -1)
131 | return;
132 |
133 | _availableCount++;
134 | Monitor.Pulse(_lock);
135 | }
136 | }
137 |
138 | ///
139 | /// Exits the semaphore the given amount. One thread can enter it and another one exit it. There is no check for that.
140 | ///
141 | public void Exit(int count)
142 | {
143 | if (count <= 0)
144 | throw new ArgumentException("count of semaphores to exit must be at least 1.", nameof(count));
145 |
146 | if (count == -1)
147 | {
148 | Exit();
149 | return;
150 | }
151 |
152 | lock(_lock)
153 | {
154 | if (_availableCount == -1)
155 | return;
156 |
157 | _availableCount += count;
158 | Monitor.PulseAll(_lock);
159 | }
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/SpinLockSlim.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System.Threading;
28 |
29 | namespace LibreMetaverse.Threading
30 | {
31 | ///
32 | /// A real slim SpinWait (the Microsoft version is slower than the normal use of
33 | /// the lock keyword for uncontended locks).
34 | /// This lock never verifies ownership, so it will dead-lock if you try
35 | /// to enter it twice and it will allow one thread to enter the lock and
36 | /// another thread to release it (if you want that, it will be great... if not,
37 | /// you will be causing bugs).
38 | /// It should only be used in situations where the lock is expected to be
39 | /// held for very short times and when performance is really critical.
40 | /// This is a struct, so if you for some reason need to pass it as a parameter,
41 | /// use it as a ref, or else you will end-up using a copy of the lock instead
42 | /// of working on the real one.
43 | ///
44 | public struct SpinLockSlim
45 | {
46 | private int _locked;
47 |
48 | ///
49 | /// Enters the lock. So you can do your actions in a safe manner.
50 | ///
51 | public void Enter()
52 | {
53 | if (Interlocked.CompareExchange(ref _locked, 1, 0) == 0)
54 | return;
55 |
56 | SpinWait spinWait = new SpinWait();
57 | while(true)
58 | {
59 | spinWait.SpinOnce();
60 |
61 | if (Interlocked.CompareExchange(ref _locked, 1, 0) == 0)
62 | return;
63 | }
64 | }
65 |
66 | ///
67 | /// Exits the lock. If the same thread exits and enters the lock constantly, it will
68 | /// probably got the lock many times before letting other threads get it, even if those
69 | /// other threads started to wait before the actual thread releases the lock. Fairness
70 | /// is not a strong point of this lock.
71 | ///
72 | public void Exit()
73 | {
74 | // There is no need to use a "volatile" write as all .NET writes
75 | // have "release" semantics.
76 | _locked = 0;
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/LibreMetaverse/Threading/SpinReaderWriterLock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024, Sjofn LLC
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System;
28 | using LibreMetaverse.Threading.Disposers;
29 |
30 | namespace LibreMetaverse.Threading
31 | {
32 | ///
33 | /// A reader writer lock that uses SpinWait if it does not have the lock. If the locks are held for
34 | /// to much time, this is CPU consuming.
35 | /// In my general tests, it is about 20 times faster than ReaderWriterLockSlim class and two times
36 | /// faster than the YieldReaderWriterLock.
37 | ///
38 | public sealed class SpinReaderWriterLock:
39 | IReaderWriterLock
40 | {
41 | #region Fields
42 | internal SpinReaderWriterLockSlim Lock;
43 | #endregion
44 |
45 | #region ReadLock
46 | ///
47 | /// Acquires a read lock that must be used in a using clause.
48 | ///
49 | public SpinReadLock ReadLock()
50 | {
51 | Lock.EnterReadLock();
52 | return new SpinReadLock(this);
53 | }
54 | #endregion
55 | #region UpgradeableLock
56 | ///
57 | /// Acquires a upgradeable read lock that must be used in a using clause.
58 | ///
59 | public SpinUpgradeableLock UpgradeableLock()
60 | {
61 | Lock.EnterUpgradeableLock();
62 | return new SpinUpgradeableLock(this);
63 | }
64 | #endregion
65 | #region WriteLock
66 | ///
67 | /// Acquires a write lock that must be used in a using clause.
68 | /// If you are using a UpgradeableLock use the Upgrade method of the
69 | /// YieldUpgradeableLock instead or you will cause a dead-lock.
70 | ///
71 | public SpinWriteLock WriteLock()
72 | {
73 | Lock.EnterWriteLock();
74 | return new SpinWriteLock(this);
75 | }
76 | #endregion
77 |
78 | #region IReaderWriterLock Members
79 | IDisposable IReaderWriterLock.ReadLock()
80 | {
81 | return ReadLock();
82 | }
83 |
84 | IUpgradeableLock IReaderWriterLock.UpgradeableLock()
85 | {
86 | return UpgradeableLock();
87 | }
88 |
89 | IDisposable IReaderWriterLock.WriteLock()
90 | {
91 | return WriteLock();
92 | }
93 | #endregion
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/LibreMetaverse/UDPPacketBuffer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 |
4 | namespace OpenMetaverse
5 | {
6 | // this class encapsulates a single packet that
7 | // is either sent or received by a UDP socket
8 | public class UDPPacketBuffer
9 | {
10 | /// Size of the byte array used to store raw packet data
11 | public const int DEFAULT_BUFFER_SIZE = 4096;
12 |
13 | /// Raw packet data buffer
14 | public readonly byte[] Data;
15 |
16 | /// Length of the data to transmit
17 | public int DataLength;
18 |
19 | /// EndPoint of the remote host
20 | public EndPoint RemoteEndPoint;
21 |
22 | ///
23 | /// Create an allocated UDP packet buffer for receiving a packet
24 | ///
25 | public UDPPacketBuffer()
26 | {
27 | Data = new byte[DEFAULT_BUFFER_SIZE];
28 | // Will be modified later by BeginReceiveFrom()
29 | RemoteEndPoint = new IPEndPoint(Settings.BIND_ADDR, 0);
30 | }
31 |
32 | ///
33 | /// Create an allocated UDP packet buffer for sending a packet
34 | ///
35 | /// EndPoint of the remote host
36 | public UDPPacketBuffer(IPEndPoint endPoint)
37 | {
38 | Data = new byte[DEFAULT_BUFFER_SIZE];
39 | RemoteEndPoint = endPoint;
40 | }
41 |
42 | ///
43 | /// Create an allocated UDP packet buffer for sending a packet
44 | ///
45 | /// EndPoint of the remote host
46 | /// Size of the buffer to allocate for packet data
47 | public UDPPacketBuffer(IPEndPoint endPoint, int bufferSize)
48 | {
49 | Data = new byte[bufferSize];
50 | RemoteEndPoint = endPoint;
51 | }
52 |
53 | ///
54 | /// Create an allocated UDP packet buffer for sending a packet
55 | ///
56 | public UDPPacketBuffer(byte[] buffer, int bufferSize, IPEndPoint destination, int category)
57 | {
58 | Data = new byte[bufferSize];
59 | this.CopyFrom(buffer, bufferSize);
60 | DataLength = bufferSize;
61 |
62 | RemoteEndPoint = destination;
63 | }
64 |
65 | ///
66 | /// Create an allocated UDP packet buffer for sending a packet
67 | ///
68 | /// EndPoint of the remote host
69 | /// The actual buffer to use for packet data (no allocation).
70 | public UDPPacketBuffer(IPEndPoint endPoint, byte[] data)
71 | {
72 | Data = data;
73 | RemoteEndPoint = endPoint;
74 | }
75 |
76 | public void CopyFrom(Array src, int length)
77 | {
78 | Buffer.BlockCopy(src, 0, this.Data, 0, length);
79 | }
80 |
81 | public void CopyFrom(Array src)
82 | {
83 | this.CopyFrom(src, src.Length);
84 | }
85 |
86 | public void ResetEndpoint()
87 | {
88 | RemoteEndPoint = new IPEndPoint(Settings.BIND_ADDR, 0);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/LibreMetaverse/UtilizationStatistics.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2006-2016, openmetaverse.co
3 | * All rights reserved.
4 | *
5 | * - Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | * - Neither the name of the openmetaverse.co nor the names
11 | * of its contributors may be used to endorse or promote products derived from
12 | * this software without specific prior written permission.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 | * POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | using System.Collections.Generic;
28 | using System.Linq;
29 |
30 | namespace OpenMetaverse.Stats
31 | {
32 | public enum Type
33 | {
34 | Packet,
35 | Message
36 | }
37 |
38 | public class UtilizationStatistics
39 | {
40 | public class Stat
41 | {
42 | public Type Type { get; set; }
43 | public long TxCount { get; set; }
44 | public long RxCount { get; set; }
45 | public long TxBytes { get; set; }
46 | public long RxBytes { get; set; }
47 | }
48 |
49 | private readonly Dictionary m_StatsCollection;
50 |
51 | public UtilizationStatistics()
52 | {
53 | m_StatsCollection = new Dictionary();
54 | }
55 |
56 | internal void Update(string key, Type type, long txBytes, long rxBytes)
57 | {
58 | lock (m_StatsCollection)
59 | {
60 | Stat stat;
61 |
62 | if (m_StatsCollection.TryGetValue(key, out var value))
63 | {
64 | stat = value;
65 | }
66 | else
67 | {
68 | stat = new Stat()
69 | {
70 | Type = type
71 | };
72 | m_StatsCollection.Add(key, stat);
73 | }
74 |
75 | if (rxBytes > 0)
76 | {
77 | stat.RxCount += 1;
78 | stat.RxBytes += rxBytes;
79 | }
80 |
81 | if (txBytes > 0)
82 | {
83 | stat.TxCount += 1;
84 | stat.TxBytes += txBytes;
85 | }
86 | }
87 | }
88 |
89 | public Dictionary GetStatistics()
90 | {
91 | lock (m_StatsCollection)
92 | {
93 | return m_StatsCollection.ToDictionary(
94 | e => e.Key,
95 | e => new Stat()
96 | {
97 | Type = e.Value.Type,
98 | RxBytes = e.Value.RxBytes,
99 | RxCount = e.Value.RxCount,
100 | TxBytes = e.Value.TxBytes,
101 | TxCount = e.Value.TxCount
102 | });
103 | }
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ```
4 | _____ _ _ _
5 | / ___| | | | | |
6 | \ `--. ___ ___ ___ _ __ __| | |__ ___ | |_
7 | `--. \/ _ \/ __/ _ \| '_ \ / _` | '_ \ / _ \| __|
8 | /\__/ / __/ (_| (_) | | | | (_| | |_) | (_) | |_
9 | \____/ \___|\___\___/|_| |_|\__,_|_.__/ \___/ \__|
10 | ```
11 | # Secondbot
12 | Secondbot is a CommandLine based bot for SecondLife based on libremetaverse retargeted for .net core.
13 |
14 | [madpeter/secondbot on dockerhub](https://hub.docker.com/r/madpeter/secondbot)
15 |
16 | Current tags
17 | ====
18 | events - the most upto date stable version of the bot
19 |
20 | debug - used for feature tested
21 |
22 |
23 | Archived tags
24 | ====
25 | classic - the older pre events update version of the bot (if you can please use a current tag)
26 |
27 |
28 |
29 | ### Status
30 | ---
31 | [](https://bestpractices.coreinfrastructure.org/projects/3765)
32 |
33 |
34 | ### Getting started guides
35 | ---
36 | Wiki / [Docker-with-Portainer](https://github.com/Madpeterz/SecondBot/wiki/Setting-up-(Docker-with-Portainer))
37 |
38 |
39 | ### Running on a pi?
40 | ---
41 | [arm32 v7 docker image provided by shadoskill](https://hub.docker.com/r/shadoskill/secondbot_arm)
42 |
43 |
--------------------------------------------------------------------------------
/SecondBotEvents/Commands/Animation.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using SecondBotEvents.Services;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 |
7 | namespace SecondBotEvents.Commands
8 | {
9 | [ClassInfo("Animations and Gestures")]
10 | internal class AnimationCommands(EventsSecondBot setmaster) : CommandsAPI(setmaster)
11 | {
12 | [About("Toggles if animation requests from this avatar (used for remote poseballs) are accepted")]
13 | [ReturnHints("Granted perm animation")]
14 | [ReturnHints("Removed perm animation")]
15 | [ReturnHintsFailure("avatar lookup")]
16 | [ArgHints("avatar", "Who to accept requests from", "AVATAR")]
17 | [CmdTypeSet()]
18 | public object AddToAllowAnimations(string avatar)
19 | {
20 | ProcessAvatar(avatar);
21 | if (avataruuid == UUID.Zero)
22 | {
23 | return BasicReply("avatar lookup", [avatar]);
24 | }
25 | // @todo accept storage
26 | return Failure("@todo");
27 | }
28 |
29 | [About("Attempts to play a gesture")]
30 | [ReturnHintsFailure("Error with gesture")]
31 | [ReturnHints("Accepted")]
32 | [ArgHints("gesture", "What gesture to trigger", "UUID")]
33 | [CmdTypeDo()]
34 | public object PlayGesture(string gesture)
35 | {
36 | if (UUID.TryParse(gesture, out UUID gestureUUID) == false)
37 | {
38 | return BasicReply("Error with gesture", [gesture]);
39 | }
40 | InventoryItem itm = GetClient().Inventory.FetchItem(gestureUUID, GetClient().Self.AgentID, TimeSpan.FromSeconds(15));
41 | GetClient().Self.PlayGesture(itm.AssetUUID);
42 | return BasicReply("Accepted", [gesture]);
43 | }
44 |
45 | [About("Resets the animation stack for the bot")]
46 | [ReturnHints("Accepted - X stopped animations")]
47 | [CmdTypeDo()]
48 | public object ResetAnimations()
49 | {
50 | List animations = [.. GetClient().Self.SignaledAnimations.Copy().Keys];
51 | foreach (UUID anim in animations)
52 | {
53 | GetClient().Self.AnimationStop(anim, true);
54 | }
55 | return BasicReply("Accepted - "+animations.Count.ToString()+" stopped animations");
56 | }
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SecondBotEvents/Commands/Core.cs:
--------------------------------------------------------------------------------
1 | using SecondBotEvents.Services;
2 |
3 | namespace SecondBotEvents.Commands
4 | {
5 | [ClassInfo("Used to test interaction with the bot... hello world for avartars")]
6 | public class Core(EventsSecondBot setmaster) : CommandsAPI(setmaster)
7 | {
8 | [About("Used to check connections")]
9 | [ReturnHints("world")]
10 | [CmdTypeGet()]
11 | public object Hello()
12 | {
13 | return BasicReply("world");
14 | }
15 | }
16 |
17 | public class CommandLibCall
18 | {
19 | public string Command { get; set; }
20 | public string[] Args { get; set; }
21 | public string AuthCode { get; set; }
22 | }
23 |
24 | public class NearMeDetails
25 | {
26 | public string id { get; set; }
27 | public string name { get; set; }
28 | public int x { get; set; }
29 | public int y { get; set; }
30 | public int z { get; set; }
31 | public int range { get; set; }
32 |
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/SecondBotEvents/Commands/Dialogs.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using SecondBotEvents.Services;
3 |
4 |
5 | namespace SecondBotEvents.Commands
6 | {
7 | [ClassInfo("Script dialog box interaction / events when displayed")]
8 | public class Dialogs(EventsSecondBot setmaster) : CommandsAPI(setmaster)
9 | {
10 | [About("adds a avatar dialog relay target [or removes if it exists]")]
11 | [ReturnHints("added")]
12 | [ReturnHints("removed")]
13 | [ReturnHintsFailure("unable to find avatar")]
14 | [ReturnHintsFailure("looking up avatar please try again")]
15 | [ArgHints("avatar", "Who to send the dialog relay to", "AVATAR")]
16 | [CmdTypeSet()]
17 | public object DialogRelayAvatarTarget(string avatar)
18 | {
19 | if(UUID.TryParse(avatar, out UUID avUUID) == false)
20 | {
21 | string avataruuid = master.DataStoreService.GetAvatarUUID(avatar);
22 | if (avataruuid == "lookup")
23 | {
24 | return Failure("looking up avatar please try again");
25 | }
26 | if (UUID.TryParse(avataruuid, out avUUID) == false)
27 | {
28 | return Failure("unable to find avatar");
29 | }
30 | }
31 | return BasicReply(master.DialogService.AvatarRelayTarget(avUUID));
32 | }
33 |
34 | [About("adds a chat dialog relay target [or removes if it exists]")]
35 | [ReturnHints("added")]
36 | [ReturnHints("removed")]
37 | [ReturnHintsFailure("channel must be zero or more")]
38 | [ReturnHintsFailure("channel is not vaild")]
39 | [ArgHints("channel", "what channel number to send the reply to (must be zero or higher)","Number", "123")]
40 | [CmdTypeSet()]
41 | public object DialogRelayChatTarget(string channel)
42 | {
43 | if (int.TryParse(channel, out int channelnum) == false)
44 | {
45 | return Failure("channel is not vaild");
46 | }
47 | if(channelnum < 0)
48 | {
49 | return Failure("channel must be zero or more");
50 | }
51 | return BasicReply(master.DialogService.ChannelRelayTarget(channelnum));
52 | }
53 |
54 | [About("adds a http dialog relay target [or removes if it exists]")]
55 | [ReturnHints("added")]
56 | [ReturnHints("removed")]
57 | [ReturnHintsFailure("url must start with http")]
58 | [ArgHints("url", "the URL to send the replys to","URL","http://mycoolsite.com/botdialog.php")]
59 | [CmdTypeSet()]
60 | public object DialogRelayHttpTarget(string url)
61 | {
62 | if(url.StartsWith("http") == false)
63 | {
64 | return Failure("url must start with http");
65 | }
66 | return BasicReply(master.DialogService.HttpRelayTarget(url));
67 | }
68 |
69 |
70 | [About("Makes the bot interact with the dialog [dialogid] with the button [buttontext]")]
71 | [ReturnHints("action")]
72 | [ReturnHintsFailure("Invaild dialog window")]
73 | [ReturnHintsFailure("Invaild dialog button")]
74 | [ReturnHintsFailure("bad dialog id")]
75 | [ArgHints("dialogid", "The ID for the dialog","Number","442")]
76 | [ArgHints("buttontext", "The button text to push","Text","Unlock")]
77 | [CmdTypeDo()]
78 | public object DialogResponce(string dialogid, string buttontext)
79 | {
80 | if (int.TryParse(dialogid, out int dialogidnum) == false)
81 | {
82 | return Failure("bad dialog id", [dialogid, buttontext]);
83 | }
84 | return BasicReply(master.DialogService.DialogAction(dialogidnum, buttontext));
85 | }
86 |
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/SecondBotEvents/Commands/Funds.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using SecondBotEvents.Services;
3 |
4 |
5 | namespace SecondBotEvents.Commands
6 | {
7 | [ClassInfo("Money makes the world go round")]
8 | public class Funds(EventsSecondBot setmaster) : CommandsAPI(setmaster)
9 | {
10 | [About("Requests the current balance and requests the balance to update.")]
11 | [ReturnHints("Current fund level")]
12 | [ReturnHintsFailure("Funds commands are disabled")]
13 | [CmdTypeGet()]
14 | public object Balance()
15 | {
16 | if (master.CommandsService.myConfig.GetAllowFundsCommands() == false)
17 | {
18 | return Failure("Funds commands are disabled");
19 | }
20 | GetClient().Self.RequestBalance();
21 | return BasicReply(GetClient().Self.Balance.ToString());
22 | }
23 |
24 | [About("Makes the bot pay a avatar")]
25 | [ReturnHints("Accepted")]
26 | [ReturnHintsFailure("avatar lookup")]
27 | [ReturnHintsFailure("Amount out of range")]
28 | [ReturnHintsFailure("Invaild amount")]
29 | [ReturnHintsFailure("Transfer funds to avatars disabled")]
30 | [ArgHints("avatar", "Who to pay", "AVATAR")]
31 | [ArgHints("amount", "the amount to pay (from 1 to current balance)", "Number", "442")]
32 | [CmdTypeDo()]
33 | public object PayAvatar(string avatar, string amount)
34 | {
35 | if (master.CommandsService.myConfig.GetAllowFundsCommands() == false)
36 | {
37 | return Failure("Transfer funds to avatars disabled", [avatar, amount]);
38 | }
39 | ProcessAvatar(avatar);
40 | if (avataruuid == UUID.Zero)
41 | {
42 | return BasicReply("avatar lookup", [avatar, amount]);
43 | }
44 | if (int.TryParse(amount, out int amountvalue) == false)
45 | {
46 | return Failure("Invaild amount", [avatar, amount]);
47 | }
48 | if ((amountvalue < 0) || (amountvalue > GetClient().Self.Balance))
49 | {
50 | GetClient().Self.RequestBalance();
51 | return Failure("Amount out of range current max: "+ GetClient().Self.Balance.ToString(), [avatar, amount]);
52 | }
53 | GetClient().Self.GiveAvatarMoney(avataruuid, amountvalue);
54 | return BasicReply("Accepted", [avatar, amount]);
55 | }
56 |
57 | [About("Makes the bot pay a object")]
58 | [ReturnHints("ok")]
59 | [ReturnHintsFailure("Primname is empty")]
60 | [ReturnHintsFailure("Invaild object UUID")]
61 | [ReturnHintsFailure("Invaild amount")]
62 | [ReturnHintsFailure("Amount out of range")]
63 | [ReturnHintsFailure("Funds commands are disabled")]
64 | [ArgHints("object", "Object to pay","UUID")]
65 | [ArgHints("primname", "The name of the prim on the object to pay","Text","MyBank")]
66 | [ArgHints("amount", "the amount to pay (from 1 to current balance)","Number","312")]
67 | [CmdTypeDo()]
68 | public object PayObject(string objectuuid,string primname,string amount)
69 | {
70 | if (master.CommandsService.myConfig.GetAllowFundsCommands() == false)
71 | {
72 | return Failure("Funds commands are disabled", [objectuuid, primname, amount]);
73 | }
74 | if (UUID.TryParse(objectuuid, out UUID objectUUID) == false)
75 | {
76 | return Failure("Invaild object UUID", [objectuuid, primname, amount]);
77 | }
78 | if (int.TryParse(amount, out int amountvalue) == false)
79 | {
80 | return Failure("Invaild amount", [objectuuid, primname, amount]);
81 | }
82 | if((amountvalue < 0) || (amountvalue > GetClient().Self.Balance))
83 | {
84 | return Failure("Amount out of range", [objectuuid, primname, amount]);
85 | }
86 | if(SecondbotHelpers.notempty(primname) == false)
87 | {
88 | return Failure("Primname is empty", [objectuuid, primname, amount]);
89 | }
90 | GetClient().Self.GiveObjectMoney(objectUUID, amountvalue, primname);
91 | return BasicReply("ok", [objectuuid, primname, amount]);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/SecondBotEvents/Commands/StreamAdmin.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using OpenMetaverse;
3 | using RestSharp;
4 | using SecondBotEvents.Services;
5 | using System;
6 |
7 | namespace SecondBotEvents.Commands
8 | {
9 | [ClassInfo("Interface for streamadmin to create notecards, you will prob never need this")]
10 | public class StreamAdmin(EventsSecondBot setmaster) : CommandsAPI(setmaster)
11 | {
12 | [About("A streamadin command")]
13 | [ReturnHints("True|False")]
14 | [ReturnHintsFailure("Bad reply: ...")]
15 | [ReturnHintsFailure("Endpoint is empty")]
16 | [ReturnHintsFailure("Endpointcode is empty")]
17 | [ReturnHintsFailure("HTTP status code: ...")]
18 | [ReturnHintsFailure("Error: ...")]
19 | [ReturnHintsFailure("Notecard title is to short")]
20 | [ArgHints("endpoint", "The end point","Text","No help given")]
21 | [ArgHints("endpointcode", "The end point code", "Text", "No help given")]
22 | [CmdTypeGet()]
23 | public object FetchNextNotecard(string endpoint, string endpointcode)
24 | {
25 | if (SecondbotHelpers.notempty(endpoint) == false)
26 | {
27 | return Failure("Endpoint is empty", [endpoint, endpointcode]);
28 | }
29 | if (SecondbotHelpers.notempty(endpointcode) == false)
30 | {
31 | return Failure("Endpointcode is empty", [endpoint, endpointcode]);
32 | }
33 |
34 | string attempt_endpoint = endpoint + "sys.php";
35 | string token = SecondbotHelpers.GetSHA1(SecondbotHelpers.UnixTimeNow().ToString() + "NotecardNext" + endpointcode);
36 | var client = new RestClient(attempt_endpoint);
37 | var request = new RestRequest("Notecard/Next", Method.Post);
38 | string unixtime = SecondbotHelpers.UnixTimeNow().ToString();
39 | request.AddParameter("token", token);
40 | request.AddParameter("unixtime", unixtime);
41 | request.AddParameter("method", "Notecard");
42 | request.AddParameter("action", "Next");
43 | request.AddHeader("content-type", "application/x-www-form-urlencoded");
44 | RestResponse endpoint_checks = client.ExecutePostAsync(request).Result;
45 | if (endpoint_checks.StatusCode != System.Net.HttpStatusCode.OK)
46 | {
47 | return Failure("HTTP status code: " + endpoint_checks.StatusCode.ToString(), [endpoint, endpointcode]);
48 | }
49 | try
50 | {
51 | NotecardEndpoint server_reply = JsonConvert.DeserializeObject(endpoint_checks.Content);
52 | if (server_reply.status == false)
53 | {
54 | return Failure("Bad reply: " + server_reply.message, [endpoint, endpointcode]);
55 | }
56 | if (server_reply.NotecardTitle.Length < 3)
57 | {
58 | return Failure("Notecard title is to short", [endpoint, endpointcode]);
59 | }
60 | ProcessAvatar(server_reply.AvatarUUID);
61 | if(avataruuid == UUID.Zero)
62 | {
63 | return Failure("Unable to unpack avatar", [endpoint, endpointcode]);
64 | }
65 | bool result = master.BotClient.SendNotecard(server_reply.NotecardTitle, server_reply.NotecardContent, avataruuid);
66 | if (result == false)
67 | {
68 | return Failure("Failed to create/send notecard", [endpoint, endpointcode]);
69 | }
70 | return BasicReply("ok");
71 | }
72 | catch (Exception e)
73 | {
74 | return Failure("Error: " + e.Message + "", [endpoint, endpointcode]);
75 | }
76 | }
77 |
78 | public class NotecardEndpoint : BasicEndpoint
79 | {
80 | public string AvatarUUID { get; set; }
81 | public string NotecardTitle { get; set; }
82 | public string NotecardContent { get; set; }
83 | }
84 |
85 | public class BasicEndpoint
86 | {
87 | public bool status { get; set; }
88 | public string message { get; set; }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/SecondBotEvents/Config/BasicConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class BasicConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "basic";
12 | settings.Add("Username");
13 | settings.Add("Password");
14 | settings.Add("LoginURI");
15 | settings.Add("LogCommands");
16 | settings.Add("DefaultHoverHeight");
17 | }
18 |
19 | public double GetDefaultHoverHeight()
20 | {
21 | return ReadSettingAsDouble("DefaultHoverHeight", 0.1);
22 | }
23 | public bool GetLogCommands()
24 | {
25 | return ReadSettingAsBool("LogCommands", true);
26 | }
27 | public string GetUsername()
28 | {
29 | return ReadSettingAsString("Username","Firstname Lastname");
30 | }
31 |
32 | public string GetPassword()
33 | {
34 | return ReadSettingAsString("Password", "passwordHere");
35 | }
36 |
37 | public string GetFirstName()
38 | {
39 |
40 | string[] bits = GetUsername().Split(" ");
41 | return bits[0];
42 | }
43 |
44 | public string GetLastName()
45 | {
46 | string[] bits = GetUsername().Split(" ");
47 | if(bits.Length == 2)
48 | {
49 | return bits[1];
50 | }
51 | return "Resident";
52 | }
53 |
54 | public string GetLoginURI()
55 | {
56 | return ReadSettingAsString("LoginURI", "secondlife");
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SecondBotEvents/Config/CommandsConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Linq;
5 |
6 | namespace SecondBotEvents.Config
7 | {
8 | public class CommandsConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
9 | {
10 | protected override void MakeSettings()
11 | {
12 | filename = "commands";
13 | settings.Add("AllowFundsCommands");
14 | settings.Add("AllowIMcontrol");
15 | settings.Add("SharedSecret");
16 | settings.Add("EnableMasterControls");
17 | settings.Add("MastersCSV");
18 | settings.Add("CheckDotNames");
19 | settings.Add("EnforceTimeWindow");
20 | settings.Add("TimeWindowSecs");
21 | settings.Add("Enabled");
22 | settings.Add("ObjectMasterOptout");
23 | settings.Add("AllowServiceControl");
24 | settings.Add("CommandHistoryLogResults");
25 | settings.Add("HideStatusOutput");
26 | }
27 |
28 |
29 | public bool GetCommandHistoryLogResults()
30 | {
31 | return ReadSettingAsBool("CommandHistoryLogResults", false);
32 | }
33 | public bool GetAllowServiceControl()
34 | {
35 | return ReadSettingAsBool("AllowServiceControl", false);
36 | }
37 | public bool GetEnabled()
38 | {
39 | return ReadSettingAsBool("Enabled", true);
40 | }
41 |
42 | public bool GetCheckDotNames()
43 | {
44 | return ReadSettingAsBool("CheckDotNames", false);
45 | }
46 |
47 | public bool GetObjectMasterOptout()
48 | {
49 | return ReadSettingAsBool("ObjectMasterOptout", false);
50 | }
51 |
52 | public string[] GetMastersCSV()
53 | {
54 | return ReadSettingAsString("MastersCSV", "Madpeter Zond").Split(",");
55 | }
56 |
57 | public bool GetEnforceTimeWindow()
58 | {
59 | return ReadSettingAsBool("EnforceTimeWindow", false);
60 | }
61 |
62 | public int GetTimeWindowSecs()
63 | {
64 | return ReadSettingAsInt("TimeWindowSecs", 35);
65 | }
66 |
67 | public bool GetEnableMasterControls()
68 | {
69 | return ReadSettingAsBool("EnableMasterControls", true);
70 | }
71 |
72 |
73 | public bool GetAllowFundsCommands()
74 | {
75 | return ReadSettingAsBool("AllowFundsCommands", false);
76 | }
77 |
78 | public bool GetAllowIMcontrol()
79 | {
80 | return ReadSettingAsBool("AllowIMcontrol", true);
81 | }
82 |
83 | public string GetSharedSecret()
84 | {
85 | return ReadSettingAsString("SharedSecret", "ThisIsMySecret");
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/SecondBotEvents/Config/CustomCommandsConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class CustomCommandsConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "customcommands";
12 | settings.Add("count");
13 | settings.Add("HideStatusOutput");
14 | int loop = 1;
15 | while(loop <= GetCount())
16 | {
17 | settings.Add(loop.ToString() + "_trigger");
18 | settings.Add(loop.ToString() + "_args");
19 | settings.Add(loop.ToString() + "_steps");
20 | int loop2 = 1;
21 | while(loop2 <= GetCommandSteps(loop))
22 | {
23 | settings.Add(loop.ToString() + "_commands_"+loop2.ToString());
24 | loop2++;
25 | }
26 | loop++;
27 | }
28 | }
29 |
30 | public string GetCommandStep(int commandIndex, int step)
31 | {
32 | return ReadSettingAsString(commandIndex.ToString() + "_commands_"+ step.ToString(), "Logoff");
33 | }
34 |
35 | public string GetCommandTrigger(int commandIndex)
36 | {
37 | return ReadSettingAsString(commandIndex.ToString() + "_trigger", "exitplease");
38 | }
39 |
40 | public int GetCommandSteps(int commandIndex)
41 | {
42 | return ReadSettingAsInt(commandIndex.ToString() + "_steps", 0);
43 | }
44 |
45 | public int GetCommandArgs(int commandIndex)
46 | {
47 | return ReadSettingAsInt(commandIndex.ToString() + "_args", 0);
48 | }
49 |
50 | public int GetCount()
51 | {
52 | return ReadSettingAsInt("count", 1);
53 | }
54 | }
55 |
56 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/DataStoreConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class DataStoreConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "datastore";
12 | settings.Add("AutoCleanAvatars");
13 | settings.Add("AvatarsCleanAfterMins");
14 | settings.Add("LocalChatHistoryLimit");
15 | settings.Add("GroupChatHistoryLimitPerGroup");
16 | settings.Add("ImChatHistoryLimit");
17 | settings.Add("PrefetchGroupMembers");
18 | settings.Add("PrefetchGroupRoles");
19 | settings.Add("PrefetchEstateBanlist");
20 | settings.Add("AutoCleanKeyValueStore");
21 | settings.Add("CleanKeyValueStoreAfterMins");
22 | settings.Add("CommandHistoryLimit");
23 | settings.Add("HideStatusOutput");
24 | }
25 |
26 |
27 | public int GetCommandHistoryLimit()
28 | {
29 | return ReadSettingAsInt("CommandHistoryLimit", 30);
30 | }
31 |
32 |
33 | public bool GetAutoCleanKeyValueStore()
34 | {
35 | return ReadSettingAsBool("AutoCleanKeyValueStore", true);
36 | }
37 |
38 | public int GetCleanKeyValueStoreAfterMins()
39 | {
40 | return ReadSettingAsInt("CleanKeyValueStoreAfterMins", 10);
41 | }
42 |
43 | public bool GetPrefetchEstateBanlist()
44 | {
45 | return ReadSettingAsBool("PrefetchEstateBanlist", true);
46 | }
47 |
48 | public bool GetPrefetchGroupRoles()
49 | {
50 | return ReadSettingAsBool("PrefetchGroupRoles", false);
51 | }
52 |
53 | public bool GetPrefetchGroupMembers()
54 | {
55 | return ReadSettingAsBool("PrefetchGroupMembers", true);
56 | }
57 |
58 | public bool GetAutoCleanAvatars()
59 | {
60 | return ReadSettingAsBool("AutoCleanAvatars", true);
61 | }
62 |
63 | public int GetAvatarsCleanAfterMins()
64 | {
65 | return ReadSettingAsInt("AvatarsCleanAfterMins", 10);
66 | }
67 |
68 | public int GetLocalChatHistoryLimit()
69 | {
70 | return ReadSettingAsInt("LocalChatHistoryLimit", 150);
71 | }
72 |
73 | public int GetGroupChatHistoryLimitPerGroup()
74 | {
75 | return ReadSettingAsInt("GroupChatHistoryLimitPerGroup", 50);
76 | }
77 |
78 | public int GetImChatHistoryLimit()
79 | {
80 | return ReadSettingAsInt("ImChatHistoryLimit", 50);
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/DialogRelayConfig.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SecondBotEvents.Config
7 | {
8 | public class DialogRelayConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
9 | {
10 | protected override void MakeSettings()
11 | {
12 | filename = "dialogrelay";
13 | settings.Add("RelayChannel");
14 | settings.Add("RelayAvatar");
15 | settings.Add("RelayObjectOwnerOnly");
16 | settings.Add("RelayHttpurl");
17 | settings.Add("HideStatusOutput");
18 | }
19 |
20 | public string GetRelayHttpurl()
21 | {
22 | return ReadSettingAsString("RelayHttpurl", "-");
23 | }
24 |
25 | public int GetRelayChannel()
26 | {
27 | return ReadSettingAsInt("RelayChannel", -1);
28 | }
29 |
30 | public string GetRelayAvatar()
31 | {
32 | return ReadSettingAsString("RelayAvatar", UUID.Zero.ToString());
33 | }
34 |
35 | public string RelayObjectOwnerOnly()
36 | {
37 | return ReadSettingAsString("RelayObjectOwnerOnly", UUID.Zero.ToString());
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/DiscordConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class DiscordConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "discord";
12 | settings.Add("Enabled");
13 | settings.Add("ServerID");
14 | settings.Add("ClientToken");
15 | settings.Add("AllowDiscordCommands");
16 | settings.Add("InteractionEnabled");
17 | settings.Add("InteractionCommandName");
18 | settings.Add("InteractionHttpTarget");
19 | settings.Add("InteractionChannelNumber");
20 | settings.Add("hideChatterName");
21 | settings.Add("HideStatusOutput");
22 | }
23 |
24 | public bool GetEnabled()
25 | {
26 | return ReadSettingAsBool("Enabled");
27 | }
28 |
29 | public bool GethideChatterName()
30 | {
31 | return ReadSettingAsBool("hideChatterName", false);
32 | }
33 |
34 | public ulong GetServerID()
35 | {
36 | return ReadSettingAsUlong("ServerID", 0);
37 | }
38 |
39 | public string GetClientToken()
40 | {
41 | return ReadSettingAsString("ClientToken","tokenPlzKThanks");
42 | }
43 |
44 | public bool GetAllowDiscordCommands()
45 | {
46 | return ReadSettingAsBool("AllowDiscordCommands");
47 | }
48 |
49 | public bool GetInteractionEnabled()
50 | {
51 | return ReadSettingAsBool("InteractionEnabled");
52 | }
53 |
54 | public string GetInteractionHttpTarget()
55 | {
56 | return ReadSettingAsString("InteractionHttpTarget", "https://localhost/interaction.php");
57 | }
58 |
59 | public string GetInteractionCommandName()
60 | {
61 | return ReadSettingAsString("InteractionCommandName","Go");
62 | }
63 |
64 | public string GetInteractionChannelNumber()
65 | {
66 | return ReadSettingAsString("InteractionChannelNumber", "-1");
67 | }
68 |
69 | public void SetInteractionEnabled(bool enabled)
70 | {
71 | mysettings["InteractionEnabled"] = enabled.ToString();
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/EventsConfig.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SecondBotEvents.Config
7 | {
8 | public class EventsConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
9 | {
10 | protected override void MakeSettings()
11 | {
12 | filename = "events";
13 | settings.Add("Enabled");
14 | settings.Add("GroupMemberJoins");
15 | settings.Add("GroupMemberLeaves");
16 | settings.Add("GroupMemberEventsGroupUUID");
17 |
18 | settings.Add("GuestEntersArea");
19 | settings.Add("GuestLeavesArea");
20 | settings.Add("GuestTrackingSimname");
21 | settings.Add("GuestTrackingParcelname");
22 |
23 |
24 | settings.Add("SimAlertMessage");
25 | settings.Add("StatusMessage");
26 | settings.Add("MoneyEvent");
27 |
28 |
29 | settings.Add("ChangeSim");
30 | settings.Add("ChangeParcel");
31 |
32 | settings.Add("OutputChannel");
33 | settings.Add("OutputIMuuid");
34 | settings.Add("OutputHttpURL");
35 | settings.Add("OutputSecret");
36 | settings.Add("HideStatusOutput");
37 | }
38 |
39 | public string GetOutputSecret()
40 | {
41 | return ReadSettingAsString("OutputSecret", "donttellanyone");
42 | }
43 |
44 | public string GetGuestTrackingSimname()
45 | {
46 | return ReadSettingAsString("GuestTrackingSimname", "example");
47 | }
48 |
49 | public string GetGuestTrackingParcelname()
50 | {
51 | return ReadSettingAsString("GuestTrackingParcelname", "example");
52 | }
53 |
54 | public string GetGroupMemberEventsGroupUUID()
55 | {
56 | return ReadSettingAsString("GroupMemberEventsGroupUUID", UUID.Zero.ToString());
57 | }
58 |
59 | public string GetOutputHttpURL()
60 | {
61 | return ReadSettingAsString("OutputHttpURL", "n/a");
62 | }
63 |
64 | public string GetOutputIMuuid()
65 | {
66 | return ReadSettingAsString("OutputIMuuid", UUID.Zero.ToString());
67 | }
68 |
69 | public int GetOutputChannel()
70 | {
71 | return ReadSettingAsInt("OutputChannel", -1);
72 | }
73 |
74 | public bool GetGroupMemberJoins()
75 | {
76 | return ReadSettingAsBool("GroupMemberJoins", true);
77 | }
78 |
79 | public bool GetGroupMemberLeaves()
80 | {
81 | return ReadSettingAsBool("GroupMemberLeaves", true);
82 | }
83 |
84 | public bool GetGuestEntersArea()
85 | {
86 | return ReadSettingAsBool("GuestEntersArea", true);
87 | }
88 |
89 | public bool GetGuestLeavesArea()
90 | {
91 | return ReadSettingAsBool("GuestLeavesArea", true);
92 | }
93 |
94 | public bool GetChangeSim()
95 | {
96 | return ReadSettingAsBool("ChangeSim", true);
97 | }
98 |
99 | public bool GetChangeParcel()
100 | {
101 | return ReadSettingAsBool("ChangeParcel", true);
102 | }
103 |
104 | public bool GetSimAlertMessage()
105 | {
106 | return ReadSettingAsBool("SimAlertMessage", true);
107 | }
108 |
109 | public bool GetStatusMessage()
110 | {
111 | return ReadSettingAsBool("StatusMessage", true);
112 | }
113 |
114 | public bool GetMoneyEvent()
115 | {
116 | return ReadSettingAsBool("MoneyEvent", true);
117 | }
118 |
119 | public bool GetEnabled()
120 | {
121 | return ReadSettingAsBool("Enabled", false);
122 | }
123 | }
124 |
125 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/HomeboundConfig.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SecondBotEvents.Config
7 | {
8 | public class HomeboundConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
9 | {
10 | protected override void MakeSettings()
11 | {
12 | filename = "homebound";
13 | settings.Add("Enabled");
14 | settings.Add("HomeSimSlUrl");
15 | settings.Add("BackupSimSLUrl");
16 | settings.Add("ReturnToHomeSimAfterMins");
17 | settings.Add("AtHomeSeekLocation");
18 | settings.Add("AtBackupSeekLocation");
19 | settings.Add("AtHomeAutoSitUuid");
20 | settings.Add("HideStatusOutput");
21 | }
22 |
23 | public string GetAtHomeAutoSitUuid()
24 | {
25 | return ReadSettingAsString("AtHomeAutoSitUuid", UUID.Zero.ToString());
26 | }
27 |
28 | public int GetReturnToHomeSimAfterMins()
29 | {
30 | return ReadSettingAsInt("ReturnToHomeSimAfterMins", 1);
31 | }
32 |
33 | public bool GetAtHomeSeekLocation()
34 | {
35 | return ReadSettingAsBool("AtHomeSeekLocation", true);
36 | }
37 |
38 | public bool GetAtBackupSeekLocation()
39 | {
40 | return ReadSettingAsBool("AtBackupSeekLocation", false);
41 | }
42 |
43 | public string GetBackupSimSLUrl()
44 | {
45 | return ReadSettingAsString("BackupSimSLUrl", "Sandbox%20Decorus/128/128/27");
46 | }
47 |
48 | public string GetHomeSimSlUrl()
49 | {
50 | return ReadSettingAsString("HomeSimSlUrl", "Viserion/46/163/23");
51 | }
52 |
53 | public bool GetEnabled()
54 | {
55 | return ReadSettingAsBool("Enabled", false);
56 | }
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/HttpConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class HttpConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "http";
12 | settings.Add("Enabled");
13 | settings.Add("HideStatusOutput");
14 | }
15 |
16 | public bool GetEnabled()
17 | {
18 | return ReadSettingAsBool("Enabled", true);
19 | }
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/InteractionConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class InteractionConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "interaction";
12 | settings.Add("AcceptTeleports");
13 | settings.Add("AcceptGroupInvites");
14 | settings.Add("AcceptInventory");
15 | settings.Add("EnableJsonOutputEvents");
16 | settings.Add("JsonOutputEventsTarget");
17 | settings.Add("AcceptFriendRequests");
18 | settings.Add("FriendRequestLevel");
19 | settings.Add("InventoryTransferLevel");
20 | settings.Add("GroupInviteLevel");
21 | settings.Add("TeleportRequestLevel");
22 | settings.Add("Enabled");
23 | settings.Add("HideStatusOutput");
24 | settings.Add("EnableDebug");
25 | }
26 |
27 | public bool GetEnableDebug()
28 | {
29 | return ReadSettingAsBool("EnableDebug", false);
30 | }
31 |
32 | public string GetFriendRequestLevel()
33 | {
34 | return ReadSettingAsString("FriendRequestLevel", "Owner");
35 | }
36 | public string GetInventoryTransferLevel()
37 | {
38 | return ReadSettingAsString("InventoryTransferLevel", "Owner");
39 | }
40 | public string GetGroupInviteLevel()
41 | {
42 | return ReadSettingAsString("GroupInviteLevel", "Owner");
43 | }
44 | public string GetTeleportRequestLevel()
45 | {
46 | return ReadSettingAsString("TeleportRequestLevel", "Owner");
47 | }
48 |
49 | public bool GetEnabled()
50 | {
51 | return ReadSettingAsBool("Enabled", true);
52 | }
53 |
54 | public bool GetAcceptTeleports()
55 | {
56 | return ReadSettingAsBool("AcceptTeleports", true);
57 | }
58 |
59 | public bool GetAcceptGroupInvites()
60 | {
61 | return ReadSettingAsBool("AcceptGroupInvites", true);
62 | }
63 |
64 | public bool GetAcceptInventory()
65 | {
66 | return ReadSettingAsBool("AcceptInventory", true);
67 | }
68 |
69 | public bool GetAcceptFriendRequests()
70 | {
71 | return ReadSettingAsBool("AcceptFriendRequests", true);
72 | }
73 |
74 | public string GetJsonOutputEventsTarget()
75 | {
76 | return ReadSettingAsString("JsonOutputEventsTarget", "none");
77 | }
78 |
79 | public bool GetEnableJsonOutputEvents()
80 | {
81 | return ReadSettingAsBool("EnableJsonOutputEvents", false);
82 | }
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/OnEventConfig.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using SecondBotEvents.Services;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace SecondBotEvents.Config
8 | {
9 | public class OnEventConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
10 | {
11 | protected override void MakeSettings()
12 | {
13 | filename = "onevent";
14 | settings.Add("Enabled");
15 | settings.Add("Count");
16 | settings.Add("WaitSecsToStart");
17 | settings.Add("HideStatusOutput");
18 | settings.Add("DebugMe");
19 | }
20 |
21 | public int GetWaitSecsToStart()
22 | {
23 | return ReadSettingAsInt("WaitSecsToStart", 10);
24 | }
25 |
26 | public void unloadEvents()
27 | {
28 | int loop = 1;
29 | while (loop <= GetCount())
30 | {
31 | if (GetEventEnabled(loop) == false)
32 | {
33 | loop++;
34 | continue;
35 | }
36 | RemoveSetting("Event" + loop.ToString() + "Enabled");
37 | RemoveSetting("Event" + loop.ToString() + "Source");
38 | RemoveSetting("Event" + loop.ToString() + "Monitor");
39 | int loop2 = 1;
40 | while (loop2 <= GetWhereCount(loop))
41 | {
42 | RemoveSetting("Event" + loop.ToString() + "Where" + loop2.ToString());
43 | loop2++;
44 | }
45 | RemoveSetting("Event" + loop.ToString() + "WhereCount");
46 | loop2 = 1;
47 | while (loop2 <= GetActionCount(loop))
48 | {
49 | settings.Remove("Event" + loop.ToString() + "Action" + loop2.ToString());
50 | loop2++;
51 | }
52 | RemoveSetting("Event" + loop.ToString() + "ActionCount");
53 | loop++;
54 | }
55 | }
56 |
57 | protected void RemoveSetting(string name)
58 | {
59 | mysettings.Remove(name);
60 | settings.Remove(name);
61 | }
62 |
63 | public bool GetDebugMe()
64 | {
65 | return ReadSettingAsBool("DebugMe", false);
66 | }
67 | public bool GetEnabled()
68 | {
69 | return ReadSettingAsBool("Enabled", false);
70 | }
71 |
72 | public int GetCount()
73 | {
74 | return ReadSettingAsInt("Count", 0);
75 | }
76 |
77 | public int GetActionCount(int oneventid)
78 | {
79 | return ReadSettingAsInt("Event" + oneventid.ToString() + "ActionCount", 0);
80 | }
81 |
82 | public string GetActionStep(int oneventid, int stepid)
83 | {
84 | return ReadSettingAsString("Event" + oneventid.ToString() + "Action" + stepid.ToString(), "");
85 | }
86 |
87 | public string GetWhereCheck(int oneventid, int checkid)
88 | {
89 | return ReadSettingAsString("Event" + oneventid.ToString() + "Where" + checkid.ToString(), "");
90 | }
91 |
92 | public int GetWhereCount(int oneventid)
93 | {
94 | return ReadSettingAsInt("Event" + oneventid.ToString() + "WhereCount", 0);
95 | }
96 |
97 | public bool GetEventEnabled(int oneventid)
98 | {
99 | return ReadSettingAsBool("Event" + oneventid.ToString() + "Enabled", false);
100 | }
101 |
102 | public string GetSource(int oneventid)
103 | {
104 | return ReadSettingAsString("Event" + oneventid.ToString() + "Source", "");
105 | }
106 | public string GetSourceMonitor(int oneventid)
107 | {
108 | return ReadSettingAsString("Event" + oneventid.ToString() + "Monitor", "");
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/RlvConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class RlvConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "rlv";
12 | settings.Add("Enabled");
13 | settings.Add("HideStatusOutput");
14 | }
15 |
16 | public bool GetEnabled()
17 | {
18 | return ReadSettingAsBool("Enabled", false);
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Config/SmtpConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SecondBotEvents.Config
6 | {
7 | public class SmtpConfig(bool fromENV, string fromFolder = "") : Config(fromENV, fromFolder)
8 | {
9 | protected override void MakeSettings()
10 | {
11 | filename = "smtp";
12 | settings.Add("Enabled");
13 | settings.Add("AllowEmailAsReplyTarget");
14 | settings.Add("AllowCommandSendMail");
15 | settings.Add("UseAllowedRecivers");
16 | settings.Add("AllowedReciversCSV");
17 | settings.Add("AllowSendAlertStatus");
18 | settings.Add("AllowSendLoginNotice");
19 | settings.Add("MailReplyAddress");
20 | settings.Add("Port");
21 | settings.Add("Host");
22 | settings.Add("useSSL");
23 | settings.Add("User");
24 | settings.Add("Token");
25 | settings.Add("SendAlertsAndLoginsTo");
26 | settings.Add("HideStatusOutput");
27 |
28 | }
29 | public bool GetUseAllowedRecivers()
30 | {
31 | return ReadSettingAsBool("UseAllowedRecivers", false);
32 | }
33 | public string[] GetAllowedRecivers()
34 | {
35 | return ReadSettingAsString("AllowedReciversCSV", "none").Split(',');
36 | }
37 | public bool GetUseSSL()
38 | {
39 | return ReadSettingAsBool("useSSL", false);
40 | }
41 |
42 | public string GetMailReplyAddress()
43 | {
44 | return ReadSettingAsString("MailReplyAddress", "me@myemail.tld");
45 | }
46 |
47 | public string GetSendAlertsAndLoginsTo()
48 | {
49 | return ReadSettingAsString("SendAlertsAndLoginsTo", "me@somewhere.tld");
50 | }
51 | public int GetPort()
52 | {
53 | return ReadSettingAsInt("Port", 587);
54 | }
55 |
56 | public string GetHost()
57 | {
58 | return ReadSettingAsString("Host", "smtp.mail.example");
59 | }
60 |
61 | public string GetUser()
62 | {
63 | return ReadSettingAsString("User", "me@email.addr.tld");
64 | }
65 |
66 | public string GetToken()
67 | {
68 | return ReadSettingAsString("Token", "none");
69 | }
70 |
71 | public bool GetEnabled()
72 | {
73 | return ReadSettingAsBool("Enabled", false);
74 | }
75 |
76 | public bool GetAllowEmailAsReplyTarget()
77 | {
78 | return ReadSettingAsBool("AllowEmailAsReplyTarget", false);
79 | }
80 |
81 | public bool GetAllowCommandSendMail()
82 | {
83 | return ReadSettingAsBool("AllowCommandSendMail", false);
84 | }
85 |
86 | public bool GetAllowSendAlertStatus()
87 | {
88 | return ReadSettingAsBool("AllowSendAlertStatus", false);
89 | }
90 |
91 | public bool GetAllowSendLoginNotice()
92 | {
93 | return ReadSettingAsBool("AllowSendLoginNotice", false);
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/SecondBotEvents/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SecondBotEvents.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SecondBotEvents.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SecondBotEvents/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "SecondBotEvents": {
4 | "commandName": "Project"
5 | },
6 | "Docker": {
7 | "commandName": "Docker"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/SecondBotEvents/RLV/RLVAttachmentInfo.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace SecondBotEvents.RLV
9 | {
10 | public class AttachmentInfo
11 | {
12 | public Primitive Prim;
13 | public InventoryItem Item;
14 | public UUID InventoryID;
15 | public UUID PrimID;
16 | public bool MarkedAttached;
17 | public AttachmentPoint Point => Prim != null ? Prim.PrimData.AttachmentPoint : AttachmentPoint.Default;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SecondBotEvents/RLV/RLVEventArgs.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Radegast Metaverse Client
3 | * Copyright(c) 2009-2014, Radegast Development Team
4 | * Copyright(c) 2016-2020, Sjofn, LLC
5 | * All rights reserved.
6 | *
7 | * Radegast is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published
9 | * by the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this program.If not, see.
19 | */
20 |
21 | using System;
22 |
23 | namespace SecondBotEvents.RLV
24 | {
25 | public class RLVEventArgs(RLVRule rule) : EventArgs
26 | {
27 | public RLVRule Rule { set; get; } = rule;
28 | }
29 | }
--------------------------------------------------------------------------------
/SecondBotEvents/RLV/RLVRule.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Radegast Metaverse Client
3 | * Copyright(c) 2009-2014, Radegast Development Team
4 | * Copyright(c) 2016-2020, Sjofn, LLC
5 | * All rights reserved.
6 | *
7 | * Radegast is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published
9 | * by the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with this program.If not, see.
19 | */
20 |
21 | using OpenMetaverse;
22 |
23 | namespace SecondBotEvents.RLV
24 | {
25 | public class RLVRule
26 | {
27 | public string Behaviour { set; get; }
28 | public string Option { set; get; }
29 | public string Param { set; get; }
30 | public UUID Sender { set; get; }
31 | public string SenderName { set; get; }
32 |
33 | public override string ToString()
34 | {
35 | return string.Format("{0}: {1}:{2}={3} [{4}]", SenderName, Behaviour, Option, Param, Sender);
36 | }
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/SecondBotEvents/SecondBotEvents.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | net9.0
5 | SecondBotEvents.Startup
6 | git rev-parse --short HEAD
7 | False
8 | False
9 | Linux
10 | settings.env
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers; buildtransitive
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | True
35 | True
36 | Resources.resx
37 |
38 |
39 |
40 |
41 | ResXFileCodeGenerator
42 | Resources.Designer.cs
43 |
44 |
45 |
46 |
47 | Always
48 |
49 |
50 |
--------------------------------------------------------------------------------
/SecondBotEvents/Services/RecoveryService.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using SecondBotEvents.Config;
3 | using System.Threading;
4 | using Timer = System.Timers.Timer;
5 | namespace SecondBotEvents.Services
6 | {
7 | public class RecoveryService(EventsSecondBot setMaster) : BotServices(setMaster)
8 | {
9 | protected Timer AutoRestartLoginTimer;
10 | protected new BasicConfig myConfig = new BasicConfig(false);
11 |
12 | public override string Status()
13 | {
14 | return "";
15 | }
16 |
17 | protected void BotClientRestart(object o, BotClientNotice e)
18 | {
19 | if(e.isStart == true)
20 | {
21 | LogFormater.Info("RecoveryService [Attached to new client]");
22 | }
23 | else if(e.isDC == true)
24 | {
25 | TriggerRecovery();
26 | }
27 |
28 | }
29 | public void TriggerRecovery()
30 | {
31 | LogFormater.Info("RecoveryService [Triggered]");
32 | if(master.BotClient != null)
33 | {
34 | if(master.BotClient.client != null)
35 | {
36 | if(master.BotClient.client.Network != null)
37 | {
38 | master.BotClient.client.Network.BeginLogout(); // attempt to flag logout
39 | }
40 | }
41 | }
42 | if (master.BotClient != null)
43 | {
44 | master.BotClient.flagLogoutExpected();
45 | }
46 | master.StopServices("RecoveryService"); // stop everything but recovery and the core bot service
47 | Thread.Sleep(2 * 1000); // give it 2 secs
48 | master.StopService("BotClientService");
49 | Thread.Sleep(75 * 1000); // wait 75 secs
50 | master.StartServices();
51 | }
52 |
53 | public override void Start(bool updateEnabled = false, bool setEnabledTo = false)
54 | {
55 | if (updateEnabled)
56 | {
57 | myConfig.setEnabled(setEnabledTo);
58 | }
59 | Stop();
60 | master.BotClientNoticeEvent += BotClientRestart;
61 | LogFormater.Info("Relay Service [Starting]");
62 | }
63 |
64 | public override void Stop()
65 | {
66 | if (running == true)
67 | {
68 | LogFormater.Info("Relay Service [Stopping]");
69 | }
70 |
71 | }
72 | }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/SecondBotEvents/Services/Services.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using SecondBotEvents.Config;
6 |
7 | namespace SecondBotEvents.Services
8 | {
9 | public abstract class BotServices(EventsSecondBot setMaster)
10 | {
11 | public EventsSecondBot master = setMaster;
12 | protected Config.Config myConfig;
13 | protected bool running = false;
14 |
15 | public void enableAndStart()
16 | {
17 | Restart(true, true);
18 | }
19 |
20 | public void changeConfig(string configKey, string configValue)
21 | {
22 | myConfig.updateKey(configKey, configValue);
23 | }
24 |
25 | public bool isRunning() { return running; }
26 |
27 | public GridClient GetClient()
28 | {
29 | if(master == null)
30 | {
31 | return null;
32 | }
33 | else if(master.BotClient == null)
34 | {
35 | return null;
36 | }
37 | return master.BotClient.client;
38 | }
39 | public virtual string Status()
40 | {
41 | return "";
42 | }
43 |
44 | public virtual void Start(bool updateEnabled = false, bool setEnabledTo = false)
45 | {
46 | running = true;
47 | }
48 | public virtual void Stop()
49 | {
50 | running = false;
51 | }
52 | public void Restart(bool updateEnabled=false, bool setEnabledTo=false)
53 | {
54 | if (running == true)
55 | {
56 | Stop();
57 | }
58 | Start(updateEnabled, setEnabledTo);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SecondBotEvents/Static/LogFormater.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace SecondBotEvents
5 | {
6 | public enum ConsoleLogLogLevel
7 | {
8 | Status,
9 | Info,
10 | Crit,
11 | Warn,
12 | Debug,
13 | };
14 | public static class LogFormater
15 | {
16 | public static string Warn(string message,bool send_to_console)
17 | {
18 | return Add(message, ConsoleLogLogLevel.Warn, send_to_console);
19 | }
20 | public static string Crit(string message, bool send_to_console)
21 | {
22 | return Add(message, ConsoleLogLogLevel.Crit, send_to_console);
23 | }
24 | public static string Info(string message, bool send_to_console)
25 | {
26 | return Add(message, ConsoleLogLogLevel.Info, send_to_console);
27 | }
28 | public static string Status(string message, bool send_to_console)
29 | {
30 | return Add(message, ConsoleLogLogLevel.Status, send_to_console);
31 | }
32 | public static string Debug(string message, bool send_to_console)
33 | {
34 | return Add(message, ConsoleLogLogLevel.Debug, send_to_console);
35 | }
36 | public static string Warn(string message)
37 | {
38 | return Warn(message, true);
39 | }
40 | public static string Crit(string message)
41 | {
42 | return Crit(message, true);
43 | }
44 | public static string Info(string message)
45 | {
46 | return Info(message, true);
47 | }
48 | public static string Status(string message)
49 | {
50 | return Status(message, true);
51 | }
52 | public static string Debug(string message)
53 | {
54 | return Debug(message, true);
55 | }
56 |
57 | public static string GetClockStamp()
58 | {
59 | var date = DateTime.Now;
60 | StringBuilder n = new();
61 | n.Append("[");
62 | if (date.Hour < 10)
63 | {
64 | n.Append("0");
65 | }
66 | n.Append(date.Hour.ToString());
67 | n.Append(":");
68 | if (date.Minute < 10)
69 | {
70 | n.Append("0");
71 | }
72 | n.Append(date.Minute.ToString());
73 | n.Append("] ");
74 | return n.ToString();
75 | }
76 |
77 | private static string Add(string message, ConsoleLogLogLevel Level, bool send_to_console = true)
78 | {
79 |
80 | StringBuilder n = new();
81 | n.Append(GetClockStamp());
82 | switch (Level)
83 | {
84 | #if DEBUG
85 | case ConsoleLogLogLevel.Debug:
86 | {
87 | n.Append("Debug - ");
88 | break;
89 | }
90 | case ConsoleLogLogLevel.Info:
91 | {
92 | n.Append("Info - ");
93 | break;
94 | }
95 | #endif
96 | case ConsoleLogLogLevel.Status:
97 | {
98 | n.Append("Status - ");
99 | break;
100 | }
101 | case ConsoleLogLogLevel.Warn:
102 | {
103 | n.Append("Warn - ");
104 | break;
105 | }
106 | case ConsoleLogLogLevel.Crit:
107 | {
108 | n.Append("Crit - ");
109 | break;
110 | }
111 | default:
112 | {
113 | n.Append("Log - ");
114 | break;
115 | }
116 | }
117 | n.Append(message);
118 | if(send_to_console == true)
119 | {
120 | Console.WriteLine(n.ToString());
121 | }
122 | return n.ToString();
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/SecondBotEvents/Static/SimpleIO.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.IO;
5 |
6 | namespace SecondBotEvents
7 | {
8 | public class SimpleIO
9 | {
10 | protected string root_folder = "";
11 | public void ChangeRoot(string A)
12 | {
13 | root_folder = A;
14 | if (root_folder != "")
15 | {
16 | if (DirExists(root_folder) == false)
17 | {
18 | System.IO.Directory.CreateDirectory(root_folder);
19 | }
20 | }
21 | }
22 | public static bool DirExists(string target_folder)
23 | {
24 | return System.IO.Directory.Exists(target_folder);
25 | }
26 | public void Delete(string filename)
27 | {
28 | System.IO.File.Delete(root_folder+"/"+filename);
29 | }
30 | public void WriteFile(string filename,string content)
31 | {
32 | if(Exists(filename) == true)
33 | {
34 | Delete(filename);
35 | }
36 | System.IO.File.WriteAllText(@""+root_folder + "/" + filename, content);
37 | }
38 |
39 | public void MarkOld(string targetfile)
40 | {
41 | System.IO.File.Move(@""+root_folder + "/" + targetfile, @"" + root_folder + "/" + targetfile+".old");
42 | }
43 | public bool Exists(string targetfile)
44 | {
45 | return File.Exists(@""+root_folder+"/" + targetfile);
46 | }
47 | public static bool FileType(string targetfile, string matchtype)
48 | {
49 | string[] bits = targetfile.Split('.');
50 | if (bits[^1] == matchtype)
51 | {
52 | return true;
53 | }
54 | return false;
55 | }
56 | public string ReadFile(string targetfile)
57 | {
58 | if (Exists(targetfile) == true)
59 | {
60 | string return_text = "";
61 | using (var Stream = new FileStream(@"" + root_folder + "/" + targetfile, FileMode.Open, FileAccess.Read))
62 | using (var StreamReader = new StreamReader(Stream))
63 | {
64 | return_text = StreamReader.ReadToEnd();
65 | }
66 | return return_text;
67 | }
68 | return "";
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/SecondBotEvents/Static/http_commands_helper.cs:
--------------------------------------------------------------------------------
1 | using SecondBotEvents.Commands;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SecondBotEvents
7 | {
8 | public static class http_commands_helper
9 | {
10 | public static Dictionary getCommandModules()
11 | {
12 | Dictionary reply = new()
13 | {
14 | { "animation", typeof(AnimationCommands) },
15 | { "avatars", typeof(Avatars) },
16 | { "chat", typeof(Chat) },
17 | { "core", typeof(Core) },
18 | { "dialogs", typeof(Dialogs) },
19 | { "discord", typeof(DiscordCommands) },
20 | { "estate", typeof(Estate) },
21 | { "friends", typeof(Friends) },
22 | { "funds", typeof(Funds) },
23 | { "group", typeof(GroupCommands) },
24 | { "info", typeof(Info) },
25 | { "inventory", typeof(InventoryCommands) },
26 | { "movement", typeof(Movement) },
27 | { "notecard", typeof(Notecard) },
28 | { "parcel", typeof(ParcelCommands) },
29 | { "self", typeof(Self) },
30 | { "streamadmin", typeof(StreamAdmin) },
31 | { "services", typeof(SecondBotEvents.Commands.Services) }
32 | };
33 | return reply;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/SecondBotEvents/Static/parcel.cs:
--------------------------------------------------------------------------------
1 | using OpenMetaverse;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace SecondBotEvents
7 | {
8 | public static class ParcelStatic
9 | {
10 | public static bool SetParcelMusic(GridClient bot, Parcel p, string url)
11 | {
12 | if (p.MusicURL != url)
13 | {
14 | p.MusicURL = url;
15 | p.Update(bot);
16 | }
17 | return true;
18 | }
19 | public static void ParcelSetFlag(ParcelFlags F, Parcel p, bool set)
20 | {
21 | if (p.Flags.HasFlag(F))
22 | {
23 | p.Flags -= F;
24 | }
25 | if (set == true)
26 | {
27 | p.Flags |= F;
28 | }
29 | }
30 | public static bool HasParcelPerm(Parcel P, GridClient bot)
31 | {
32 | bool has_perm = true;
33 | if (P.OwnerID != bot.Self.AgentID)
34 | {
35 | if (P.IsGroupOwned)
36 | {
37 | if (bot.Groups.GroupName2KeyCache.ContainsKey(P.GroupID) == true)
38 | {
39 | bot.Groups.ActivateGroup(P.GroupID);
40 | }
41 | else
42 | {
43 | has_perm = false;
44 | }
45 | }
46 | else
47 | {
48 | if(bot.Network.CurrentSim.IsEstateManager == false)
49 | {
50 | has_perm = false;
51 | }
52 | }
53 | }
54 | return has_perm;
55 |
56 | }
57 | public static string[] GetFlagNames()
58 | {
59 | System.Type enumType = typeof(ParcelFlags);
60 | List flagnames = new(System.Enum.GetNames(enumType));
61 | flagnames.Remove("None");
62 | return [.. flagnames];
63 | }
64 |
65 | public static Dictionary GetMediaList()
66 | {
67 | Dictionary flags = new()
68 | {
69 | { "MediaAutoScale", "Bool (True|False)" },
70 | { "MediaLoop", "Bool (True|False)" },
71 | { "MediaID", "UUID (Texture)" },
72 | { "MediaURL", "String" },
73 | { "MediaDesc", "String" },
74 | { "MediaHeight", "Int (256 to 1024)" },
75 | { "MediaWidth", "Int (256 to 1024)" },
76 | { "MediaType", "String [\"IMG-PNG\",\"IMG-JPG\",\"VID-MP4\",\"VID-AVI\" or \"Custom-MIME_TYPE_CODE\"]" }
77 | };
78 | return flags;
79 | }
80 | public static Dictionary GetFlagsList()
81 | {
82 | Dictionary flags = [];
83 | Type enumType = typeof(ParcelFlags);
84 | Array enumValues = Enum.GetValues(enumType);
85 | Array enumNames = Enum.GetNames(enumType);
86 | for (int i = 0; i < enumValues.Length; i++)
87 | {
88 | object value = enumValues.GetValue(i);
89 | ParcelFlags realValue = (ParcelFlags)value;
90 | if (realValue != 0)
91 | {
92 | string name = (string)enumNames.GetValue(i);
93 | flags.Add(name, realValue);
94 | }
95 | }
96 | return flags;
97 | }
98 |
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/SecondBotEvents/Static/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | [[PAGETITLE]]
7 |
8 |
20 |
21 |
22 |