[
  {
    "path": ".editorconfig",
    "content": "[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\nindent_style = space\nindent_size = 2\n\n[*.{js,ts}]\nindent_style = space\nindent_size = 2\n\n[*.{cs}]\nindent_style = tab\nindent_size = 2\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: endel # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncustom: https://www.paypal.me/endeld # Replace with a single custom sponsorship URL\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\nLooking for help? Post on the forum instead: http://discuss.colyseus.io\n-->\n"
  },
  {
    "path": ".github/workflows/nuget-publish.yml",
    "content": "name: NuGet Publish\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n\njobs:\n  build:\n    name: Build & Test\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: |\n            8.0.x\n            10.0.x\n\n      - name: Test\n        run: dotnet test nuget/Colyseus.csproj --filter \"FullyQualifiedName!~IntegrationTest\" --verbosity normal\n\n  publish:\n    name: Publish to NuGet\n    runs-on: ubuntu-latest\n    needs: [build]\n    if: github.event_name == 'push' && github.ref == 'refs/heads/master'\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: |\n            8.0.x\n            10.0.x\n\n      - name: Check for version change\n        id: version\n        run: |\n          CURRENT=$(python3 -c \"import json; print(json.load(open('Assets/Colyseus/package.json'))['version'])\")\n          PREVIOUS=$(git show HEAD~1:Assets/Colyseus/package.json 2>/dev/null | python3 -c \"import sys,json; print(json.load(sys.stdin)['version'])\" 2>/dev/null || echo \"\")\n          echo \"current=$CURRENT\" >> $GITHUB_OUTPUT\n          echo \"previous=$PREVIOUS\" >> $GITHUB_OUTPUT\n          if [ \"$CURRENT\" != \"$PREVIOUS\" ]; then\n            echo \"changed=true\" >> $GITHUB_OUTPUT\n            echo \"Version changed: $PREVIOUS -> $CURRENT\"\n          else\n            echo \"changed=false\" >> $GITHUB_OUTPUT\n            echo \"Version unchanged: $CURRENT\"\n          fi\n\n      - name: Pack\n        if: steps.version.outputs.changed == 'true'\n        run: |\n          dotnet pack nuget/Colyseus.csproj -c Release -o $GITHUB_WORKSPACE/packages/\n          dotnet nuget add source $GITHUB_WORKSPACE/packages/ --name local\n          dotnet pack nuget-monogame/Colyseus.MonoGame.csproj -c Release -o $GITHUB_WORKSPACE/packages/\n\n      - name: Publish to NuGet\n        if: steps.version.outputs.changed == 'true'\n        env:\n          NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}\n        run: dotnet nuget push $GITHUB_WORKSPACE/packages/*.nupkg --api-key \"$NUGET_API_KEY\" --source https://api.nuget.org/v3/index.json --skip-duplicate\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: Tests\n\non:\n  push:\n    branches: [master, universal]\n  pull_request:\n    branches: [master, universal]\n\njobs:\n  unit-tests:\n    name: Unit Tests\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: |\n            8.0.x\n            10.0.x\n\n      - name: Run unit tests\n        run: dotnet test nuget/Colyseus.csproj --filter \"FullyQualifiedName!~IntegrationTest\" --verbosity normal\n\n  integration-tests:\n    name: Integration Tests\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: |\n            8.0.x\n            10.0.x\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n\n      - name: Clone test server\n        run: git clone https://github.com/colyseus/sdks-test-server.git sdks-test-server\n\n      - name: Install test server dependencies\n        working-directory: sdks-test-server\n        run: npm install\n\n      - name: Start test server\n        working-directory: sdks-test-server\n        run: npx tsx src/index.ts > ../server.log 2>&1 &\n\n      - name: Wait for server to be ready\n        run: |\n          for i in $(seq 1 30); do\n            if curl -s http://localhost:2567 > /dev/null 2>&1; then\n              echo \"Server is ready!\"\n              exit 0\n            fi\n            echo \"Waiting for server... ($i/30)\"\n            sleep 1\n          done\n          echo \"Server failed to start\"\n          cat server.log\n          exit 1\n\n      - name: Run integration tests\n        run: dotnet test nuget/Colyseus.csproj --filter \"FullyQualifiedName~IntegrationTest\" --verbosity normal\n\n      - name: Print server logs\n        if: always()\n        run: cat server.log || true\n"
  },
  {
    "path": ".github/workflows/upmsemver.yml",
    "content": "name: Update Unity UPM semantic versioning\n\non:\n  push:\n    branches:\n      - master\n      - dev\n\njobs:\n  checkSemver:\n    name: Check for Semver Change\n    runs-on: ubuntu-latest\n    outputs:\n      semver-updated: ${{ steps.check.outputs.changed }}\n    steps:\n      - name: Checkout Code\n        uses: actions/checkout@v2\n      - uses: EndBug/version-check@v2\n        id: check\n        with:\n          file-name: Assets/Colyseus/package.json\n          diff-search: true\n  updateUPM:\n    name: Update UPM branch\n    runs-on: ubuntu-latest\n    needs: [checkSemver]\n    if: needs.checkSemver.outputs.semver-updated == 'true'\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: Fetch NativeWebSocket\n        run: bash unity-setup.sh\n\n      - name: Remove test symlink\n        run: rm -rf Assets/Colyseus/Tests\n\n      - name: Push package directory to subtree\n        uses: s0/git-publish-subdir-action@develop\n        env:\n          REPO: self\n          BRANCH: upm\n          FOLDER: Assets/Colyseus/\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n  createPackage:\n    name: Create Unity Package and Release\n    runs-on: ubuntu-latest\n    needs: [checkSemver]\n    if: needs.checkSemver.outputs.semver-updated == 'true'\n    steps:\n    - name: Checkout Code\n      uses: actions/checkout@v2\n    - name: Fetch NativeWebSocket\n      run: bash unity-setup.sh\n    - name: Remove test symlink\n      run: rm -rf Assets/Colyseus/Tests\n    - name: Gather files\n      run: |\n        echo \"Assets/Colyseus.meta\" > metaList\n        find Assets/Colyseus/ -name \\*.meta >> metaList\n    - name: Extract Version\n      id: version\n      uses: notiz-dev/github-action-json-property@release\n      with:\n          path: 'Assets/Colyseus/package.json'\n          prop_path: 'version'\n    - run: echo ${{steps.version.outputs.prop}}\n    - name: Create Directory\n      run: mkdir Release\n    - name: Generate Unity Package\n      id: build-package\n      uses: pCYSl5EDgo/create-unitypackage@v1.2.3\n      with:\n        package-path: 'Colyseus_Plugin.unitypackage'\n        include-files: metaList\n    - name: Upload Package\n      uses: actions/upload-artifact@master\n      with:\n        path: ./Colyseus_Plugin.unitypackage\n        name: Colyseus_Plugin\n    - name: Changelog\n      uses: scottbrenner/generate-changelog-action@master\n      id: Changelog\n    - name: Create Release\n      id: create_release\n      uses: actions/create-release@v1\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        tag_name: ${{ steps.version.outputs.prop }}\n        release_name: ${{ steps.version.outputs.prop }}\n        body: |\n            ${{ steps.Changelog.outputs.changelog }}\n        draft: false\n        prerelease: false\n    - name: Upload Release Asset\n      id: upload-release-asset\n      uses: actions/upload-release-asset@v1\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      with:\n        upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps\n        asset_path: ./Colyseus_Plugin.unitypackage\n        asset_name: Colyseus_Plugin.unitypackage\n        asset_content_type: application/x-gzip\n"
  },
  {
    "path": ".gitignore",
    "content": "# Server build files\nServer/build\n\n# NuGet Dependencies\n/Assets/Colyseus/Runtime/WebSocket\n\n#User Specific\n*.userprefs\n*.usertasks\n.DS_Store\n.vs/\n.vsconfig\n.idea/\n\n#Mono Project Files\n*.pidb\n*.resources\ntest-results/\nbin\nobj\n\n#NuGet packages\nColyseus/packages\n!packages/repositories.config\n\n# Node.js\nnode_modules\nnpm-debug.log\npackage-lock.json\n\n# Unity\n/[Ll]ibrary/\n/[Tt]emp/\n/[Oo]bj/\n/[Bb]uild/\n/[Bb]uilds/\n/Assets/AssetStoreTools*\n/Assets/Colyseus/Runtime/Example/\n\n# Autogenerated VS/MD/Consulo solution and project files\nExportedObj/\n.consulo/\n*.csproj\n!nuget/**/*.csproj\n!nuget-monogame/**/*.csproj\n*.unityproj\n*.sln\n*.suo\n*.tmp\n*.user\n*.userprefs\n*.pidb\n*.booproj\n*.svd\n\n# Godot\n*.uid\n\n# Unity3D Generated File On Crash Reports\nsysinfo.txt\n\n# Builds\n*.apk\n*.unitypackage\n\n# Logs\n/Logs/\n"
  },
  {
    "path": "Assets/Colyseus/.editorconfig",
    "content": "[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\nindent_style = tab\nindent_size = 4\n\n[*.{js,ts}]\nindent_style = space\nindent_size = 2\n\n[*.{cs}]\nindent_style = tab\nindent_size = 4\n"
  },
  {
    "path": "Assets/Colyseus/.gitignore",
    "content": "#User Specific\n*.userprefs\n*.usertasks\n.DS_Store\n.vs/\n\n#Mono Project Files\n*.pidb\n*.resources\ntest-results/\nbin\nobj\n\n#NuGet packages\nColyseus/packages\n!packages/repositories.config\n\n# Node.js\nnode_modules\nnpm-debug.log\npackage-lock.json\n\n# Unity\n/[Ll]ibrary/\n/[Tt]emp/\n/[Oo]bj/\n/[Bb]uild/\n/[Bb]uilds/\n/Assets/AssetStoreTools*\n\n# Autogenerated VS/MD/Consulo solution and project files\nExportedObj/\n.consulo/\n*.csproj\n*.unityproj\n*.sln\n*.suo\n*.tmp\n*.user\n*.userprefs\n*.pidb\n*.booproj\n*.svd\n\n\n# Unity3D Generated File On Crash Reports\nsysinfo.txt\n\n# Builds\n*.apk\n*.unitypackage\n\n# Logs\n/Logs/\n"
  },
  {
    "path": "Assets/Colyseus/Documentation~/.gitkeep",
    "content": ""
  },
  {
    "path": "Assets/Colyseus/Documentation~/GettingStarted.md",
    "content": "﻿\n# Unity SDK\nFor more information, please visit our [documentation site](https://docs.colyseus.io/)\n\n# Setup\n\nHere we'll be going over the steps to get your Unity client up and running and connected to a Colyseus server. \n\nTopics covered include:\n\n- Running the server locally\n- Server settings\n- Connecting to a server\n- Connecting to a room\n- Communicating with a room, and the room's state. \n\nThe topics should be enough for you to set up a basic client on your own, however, you are welcome to use and modify the included example code to suit your needs.\n\n## Running the server locally\n\nTo run the demonstration server locally, run the following commands in your terminal:\n\n```\ncd Server\nnpm install\nnpm start\n```\n\nThe built-in demonstration comes with a single [room handler](https://github.com/colyseus/colyseus-unity3d/blob/master/Server/src/rooms/MyRoom.ts), containing a suggested way of handling entities and players. Feel free to change all of it to fit your needs!\n\n## Creating a Colyseus Settings Object:\n\n- Right-click anywhere in the Project folder, select \"Create\", select \"Colyseus\", and click \"Generate ColyseusSettings Scriptable Object\"\n- Fill in the fields as necessary.\n  - **Server Address**\n    - The address to your Colyseus server.\n  - **Server Port**\n    - The port to your Colyseus server.\n  - **Use secure protocol**\n    - Check this if requests and messages to your server should use the \"https\" and \"wss\" protocols.\n  - **Default headers**\n    - You can add an unlimited number of default headers for non web socket requests to your server.\n    - The default headers are used by the `ColyseusRequest` class.\n    - An example header could have a `\"Name\"` of `\"Content-Type\"` and a `\"Value\"` of `\"application/json\"`\n\n## Colyseus Manager:\n\n- You will need to create your own Manager script that inherits from `ColyseusManager` or use and modify the provided `ExampleManager`.\n```csharp\npublic class ExampleManager : ColyseusManager<ExampleManager>\n```\n- Make an in-scene manager object to host your custom Manager script.\n- Provide your Manager with a reference to your Colyseus Settings object in the scene inspector.\n\n## Client:\n\n- Call the `InitializeClient()` method of your Manager to create a `ColyseusClient` object which is stored in the `client` variable of `ColyseusManager`. This will be used to create/join rooms and form a connection with the server.\n```csharp\nExampleManager.Instance.InitializeClient();\n```\n- If your Manager has additional classes that need reference to your `Client`, you can override `InitializeClient` and make those connections in there.\n```csharp\n//In ExampleManager.cs\npublic override void InitializeClient()\n{\n    base.InitializeClient();\n    //Pass the newly created Client reference to our RoomController\n    _roomController.SetClient(client);\n}\n```\n- You can get available rooms on the server by calling `GetAvailableRooms` of `ColyseusClient`:\n```csharp\nreturn await GetAvailableRooms<ColyseusRoomAvailable>(roomName, headers);\n```\n\n## Connecting to a Room:\n\n- There are several ways to create and/or join a room.\n- You can create a room by calling the `Create` method of `ColyseusClient` which will automatically create an instance of the room on the server and join it:\n```csharp\nExampleRoomState room = await client.Create<ExampleRoomState>(roomName);\n```\n\n- You can join a specific room by calling `JoinById`:\n```csharp\nExampleRoomState room = await client.JoinById<ExampleRoomState>(roomId);\n```\n\n- You can call the `JoinOrCreate` method of `ColyseusClient` which will matchmake into an available room, if able to, or will create a new instance of the room and then join it on the server:\n```csharp\nExampleRoomState room = await client.JoinOrCreate<ExampleRoomState>(roomName);\n```\n\n## Room Options:\n\n- When creating a new room you have the ability to pass in a dictionary of room options, such as a minimum number of players required to start a game or the name of the custom logic file to run on your server.\n- Options are of type `object` and are keyed by the type `string`:\n```csharp\nDictionary<string, object> roomOptions = new Dictionary<string, object>\n{\n    [\"YOUR_ROOM_OPTION_1\"] = \"option 1\",\n    [\"YOUR_ROOM_OPTION_2\"] = \"option 2\"\n};\n\nExampleRoomState room = await ExampleManager.Instance.JoinOrCreate<ExampleRoomState>(roomName, roomOptions);\n```\n\n## Room Events:\n\n`ColyseusRoom` has various events that you will want to subscribe to:\n\n### OnJoin\n- Gets called after the client has successfully connected to the room.\n\n### OnLeave\n- Gets called after the client has been disconnected from the room.\n- Has a `WebSocketCloseCode` parameter with the reason for the disconnection.\n```csharp\nroom.OnLeave += OnLeaveRoom;\n```\n\n### OnStateChange\n- Any time the room's state changes, including the initial state, this event will get fired.\n\n```csharp\nroom.OnStateChange += OnStateChangeHandler;\nprivate static void OnStateChangeHandler(ExampleRoomState state, bool isFirstState)\n{\n    // Do something with the state\n}\n```\n\n### OnError\n- When a room related error occurs on the server it will be reported with this event.\n- Has parameters for an error code and an error message.\n\n## Room Messages:\nYou have the ability to listen for or to send custom messages from/to a room instance on the server.\n\n### OnMessage\n- To add a listener you call `OnMessage` passing in the type and the action to be taken when that message is received by the client.\n- Messages are useful for events that occur in the room on the server. (Take a look at our [tech demos](https://docs.colyseus.io/demo/shooting-gallery/) for use case examples of using `OnMessage`)\n\n```csharp\nroom.OnMessage<ExampleNetworkedUser>(\"onUserJoin\", currentNetworkedUser =>\n{\n    _currentNetworkedUser = currentNetworkedUser;\n});\n```\n\n### Send\n- To send a custom message to the room on the server use the `Send` method of `ColyseusRoom`\n- Specify the `type` and an optional `message` parameters to send to your room.\n\n```csharp\nroom.Send(\"createEntity\", new EntityCreationMessage() { creationId = creationId, attributes = attributes });\n```\n\n### Room State:\n> See how to generate your `RoomState` from [State Handling](https://docs.colyseus.io/state/schema/#client-side-schema-generation)\n\n- Each room holds its own state. The mutations of the state are synchronized automatically to all connected clients.\n- In regards to room state synchronization:\n  - When the user successfully joins the room, they receive the full state from the server.\n  - At every `patchRate`, binary patches of the state are sent to every client (default is 50ms)\n  - `onStateChange` is called on the client-side after every patch received from the server.\n  - Each serialization method has its own particular way to handle incoming state patches.\n- `ColyseusRoomState` is the base room state you will want your room state to inherit from.\n- Take a look at our tech demos for implementation examples of synchronizable data in a room&#39;s state such as networked entities, networked users, or room attributes. ([Shooting Gallery Tech Demo](https://docs.colyseus.io/demo/shooting-gallery/))\n\n```csharp\npublic class ExampleRoomState : Schema\n{\n    [Type(0, \"map\", typeof(MapSchema<ExampleNetworkedEntity>))]\n    public MapSchema<ExampleNetworkedEntity> networkedEntities = new MapSchema<ExampleNetworkedEntity>();\n    \n    [Type(1, \"map\", typeof(MapSchema<ExampleNetworkedUser>))]\n    public MapSchema<ExampleNetworkedUser> networkedUsers = new MapSchema<ExampleNetworkedUser>();\n    \n    [Type(2, \"map\", typeof(MapSchema<string>), \"string\")]\n    public MapSchema<string> attributes = new MapSchema<string>();\n}\n```\n\n## Debugging\n\nIf you set a breakpoint in your application while the WebSocket connection is open, the connection will be closed automatically after 3 seconds due to inactivity. To prevent the WebSocket connection from dropping, use `pingInterval: 0` in your server code during development:\n\n```typescript\nimport { Server, RedisPresence } from \"colyseus\";\n\nconst gameServer = new Server({\n  // ...\n  pingInterval: 0 // HERE\n});\n```\n\nMake sure to have a `pingInterval` higher than `0` on production. The default `pingInterval` value is `3000`.\n\n"
  },
  {
    "path": "Assets/Colyseus/Editor/Colyseus.Editor.asmdef",
    "content": "{\n    \"name\": \"Colyseus.Editor\",\n    \"rootNamespace\": \"ColyseusEditor\",\n    \"references\": [\n        \"ColyseusSDK\"\n    ],\n    \"includePlatforms\": [\n        \"Editor\"\n    ],\n    \"excludePlatforms\": [],\n    \"allowUnsafeCode\": false,\n    \"overrideReferences\": false,\n    \"precompiledReferences\": [],\n    \"autoReferenced\": true,\n    \"defineConstraints\": [],\n    \"versionDefines\": [],\n    \"noEngineReferences\": false\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Editor/Colyseus.Editor.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: e4cb50f060ca4467c819ea269f994a8b\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Editor/README.md",
    "content": "# Colyseus Room Inspector\n\nUnity Editor tool for inspecting connected Colyseus room states in real-time during Play mode.\n\n## Usage\n\n1. Open **Window > Colyseus > Room Inspector**\n2. Enter Play mode and connect to a Colyseus server\n3. Active rooms are automatically discovered and displayed\n\n### Toolbar\n\n| Button | Description |\n|--------|-------------|\n| **Auto Refresh** | Toggle automatic updates (every 0.5s) |\n| **Refresh Now** | Manually refresh the display |\n| **Copy State JSON** | Copy current state to clipboard |\n\n### Example Output\n\nGiven a room with `MapSchema<Player> players` and `float gameTime`:\n\n```\nRoom: my_room (abc123)\n  +-- Connection Info\n  |   +-- Room ID: abc123\n  |   +-- Session ID: xyz789\n  |   +-- Connection: Connected\n  |   +-- Source Object: NetworkManager\n  +-- Room State\n      +-- State Type: MyRoomState\n      +-- players (MapSchema) [2 items]\n      |   +-- [player1] (Player)\n      |   |   +-- x: 10.5\n      |   |   +-- y: 20.3\n      |   |   +-- name: \"Alice\"\n      |   +-- [player2] (Player)\n      |       +-- x: 15.2\n      |       +-- y: 18.7\n      |       +-- name: \"Bob\"\n      +-- gameTime: 45.2\n```\n\n## Supported Types\n\n- Primitives (int, float, string, bool)\n- Nested Schema objects\n- `MapSchema<T>` and `ArraySchema<T>` collections\n\n## Limitations\n\n- **Play mode only** -- not available in Edit mode\n- **Read-only** -- cannot edit state values\n- Collections limited to **100 items** displayed\n- Nesting limited to **10 levels** deep\n\n## Troubleshooting\n\n**\"No active Colyseus rooms found\"** -- Ensure you are in Play mode and have connected to a room. The inspector discovers rooms by scanning MonoBehaviour fields via reflection.\n\n**State shows as \"null\"** -- The room is connected but hasn't received the initial state yet. Wait a moment or check your server-side room.\n\n**Values not updating** -- Check that Auto Refresh is enabled in the toolbar and that the room is still connected.\n"
  },
  {
    "path": "Assets/Colyseus/Editor/README.md.meta",
    "content": "fileFormatVersion: 2\nguid: 6aa8c0736e5e54df49e298b67fd58dcc\nTextScriptImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Editor/RoomInspector.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing Colyseus;\nusing Colyseus.Schema;\nusing UnityEditor;\nusing UnityEngine;\nusing System.Text;\nusing GameDevWare.Serialization;\n\nnamespace Colyseus.Editor\n{\n    /// <summary>\n    /// Static initializer to automatically capture message types from rooms\n    /// </summary>\n    static class RoomMessageType\n    {\n        // Shared storage for message types across all rooms\n        public static readonly Dictionary<string, Dictionary<string, object>> CapturedMessageTypes = new Dictionary<string, Dictionary<string, object>>();\n\n        [UnityEditor.InitializeOnLoadMethod]\n        private static void Initialize()\n        {\n            // Subscribe to play mode state changes to reset tracking\n            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;\n        }\n\n        private static void OnPlayModeStateChanged(PlayModeStateChange state)\n        {\n            if (state == PlayModeStateChange.ExitingPlayMode || state == PlayModeStateChange.EnteredEditMode)\n            {\n                // Clear captured data when exiting play mode\n                CapturedMessageTypes.Clear();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Unity Editor window for inspecting connected Colyseus room states in real-time\n    /// </summary>\n    public class RoomInspector : EditorWindow\n    {\n        private Vector2 _scrollPosition;\n        private bool _autoRefresh = true;\n        private double _lastRefreshTime;\n        private const double RefreshInterval = 0.5; // Refresh every 0.5 seconds\n        private Dictionary<string, bool> _foldouts = new Dictionary<string, bool>();\n        private Dictionary<string, Dictionary<string, string>> _messageInputs = new Dictionary<string, Dictionary<string, string>>();\n        private Dictionary<string, int> _selectedMessageTypeIndex = new Dictionary<string, int>();\n        private Dictionary<string, string> _lastSelectedMessageType = new Dictionary<string, string>();\n        private Dictionary<string, string> _rawJsonInputs = new Dictionary<string, string>();\n        private Dictionary<string, bool> _useRawJson = new Dictionary<string, bool>();\n        private Dictionary<string, string> _customMessageTypes = new Dictionary<string, string>();\n\n        // Splitter state for Room State / Messages sections\n        private Dictionary<string, float> _roomSplitterPosition = new Dictionary<string, float>();\n        private Dictionary<string, bool> _isResizingRoomSplitter = new Dictionary<string, bool>();\n        private const float MinPanelHeight = 150f;\n        private const float SplitterHeight = 4f;\n\n        // Tab selection for rooms\n        private int _selectedRoomIndex = 0;\n\n        [MenuItem(\"Window/Colyseus/Room Inspector (experimental)\")]\n        public static void ShowWindow()\n        {\n\t\t\tDebug.LogWarning(\"The Colyseus Room Inspector is experimental. Please report any issues to https://github.com/colyseus/colyseus-unity-sdk/issues\");\n            var window = GetWindow<RoomInspector>(\"Colyseus Room Inspector\");\n            window.minSize = new Vector2(400, 300);\n            window.Show();\n        }\n\n        private void OnEnable()\n        {\n            EditorApplication.update += OnEditorUpdate;\n        }\n\n        private void OnDisable()\n        {\n            EditorApplication.update -= OnEditorUpdate;\n        }\n\n        private void OnEditorUpdate()\n        {\n            if (_autoRefresh && EditorApplication.timeSinceStartup - _lastRefreshTime > RefreshInterval)\n            {\n                _lastRefreshTime = EditorApplication.timeSinceStartup;\n                Repaint();\n            }\n        }\n\n        private void OnGUI()\n        {\n            DrawToolbar();\n\n            var rooms = FindAllColyseusRooms();\n\n            if (rooms.Count == 0)\n            {\n                EditorGUILayout.HelpBox(\n                    \"No active Colyseus rooms found.\\n\\n\" +\n                    \"Make sure:\\n\" +\n                    \"• A scene is running (Play mode)\\n\" +\n                    \"• You have a MonoBehaviour with a Room field\\n\" +\n                    \"• The room is connected to the server\",\n                    MessageType.Info\n                );\n                return;\n            }\n\n            // Draw room tabs\n            DrawRoomTabs(rooms);\n\n            _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);\n\n            // Ensure selected index is valid\n            if (_selectedRoomIndex >= rooms.Count)\n            {\n                _selectedRoomIndex = 0;\n            }\n\n            // Draw selected room content\n            if (rooms.Count > 0 && _selectedRoomIndex >= 0 && _selectedRoomIndex < rooms.Count)\n            {\n                DrawRoomContent(rooms[_selectedRoomIndex]);\n            }\n\n            EditorGUILayout.EndScrollView();\n        }\n\n        private void DrawRoomTabs(List<RoomInfo> rooms)\n        {\n            EditorGUILayout.BeginHorizontal();\n\n            for (int i = 0; i < rooms.Count; i++)\n            {\n                var room = rooms[i];\n                var tabLabel = !string.IsNullOrEmpty(room.Name) ? room.Name : $\"Room {i + 1}\";\n\n                // Add connection status indicator\n                var statusIcon = room.IsConnected ? \"●\" : \"○\";\n                tabLabel = $\"{statusIcon} {tabLabel}\";\n\n                // Create tab style based on selection\n                var tabStyle = new GUIStyle(EditorStyles.toolbarButton);\n                if (i == _selectedRoomIndex)\n                {\n                    tabStyle.fontStyle = FontStyle.Bold;\n                    tabStyle.normal.textColor = EditorGUIUtility.isProSkin\n                        ? new Color(0.4f, 0.8f, 1f)\n                        : new Color(0.1f, 0.4f, 0.8f);\n                }\n\n                if (GUILayout.Toggle(i == _selectedRoomIndex, tabLabel, tabStyle))\n                {\n                    _selectedRoomIndex = i;\n                }\n            }\n\n            GUILayout.FlexibleSpace();\n            EditorGUILayout.EndHorizontal();\n\n            // Draw separator line below tabs\n            var rect = EditorGUILayout.GetControlRect(false, 2);\n            EditorGUI.DrawRect(rect, new Color(0.3f, 0.3f, 0.3f, 0.5f));\n            EditorGUILayout.Space(5);\n        }\n\n        private void DrawToolbar()\n        {\n            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);\n\n            _autoRefresh = GUILayout.Toggle(_autoRefresh, \"Auto Refresh\", EditorStyles.toolbarButton, GUILayout.Width(100));\n\n            GUILayout.FlexibleSpace();\n\n            if (GUILayout.Button(\"Refresh Now\", EditorStyles.toolbarButton, GUILayout.Width(100)))\n            {\n                Repaint();\n            }\n\n            if (GUILayout.Button(\"Copy State JSON\", EditorStyles.toolbarButton, GUILayout.Width(120)))\n            {\n                CopyStateToClipboard();\n            }\n\n            EditorGUILayout.EndHorizontal();\n            EditorGUILayout.Space(5);\n        }\n\n        private void CopyStateToClipboard()\n        {\n            try\n            {\n                var rooms = FindAllColyseusRooms();\n                if (rooms.Count == 0)\n                {\n                    EditorUtility.DisplayDialog(\"Copy State\", \"No active rooms found to copy.\", \"OK\");\n                    return;\n                }\n\n                // Ensure selected index is valid\n                if (_selectedRoomIndex >= rooms.Count)\n                {\n                    _selectedRoomIndex = 0;\n                }\n\n                var room = rooms[_selectedRoomIndex];\n                var stateData = new System.Text.StringBuilder();\n                stateData.AppendLine(\"=== Colyseus Room State ===\");\n                stateData.AppendLine($\"Captured at: {DateTime.Now:yyyy-MM-dd HH:mm:ss}\");\n                stateData.AppendLine();\n\n                stateData.AppendLine($\"Room: {room.Name} ({room.RoomId})\");\n                stateData.AppendLine($\"Session ID: {room.SessionId}\");\n                stateData.AppendLine($\"Connected: {room.IsConnected}\");\n                stateData.AppendLine();\n\n                if (room.State != null)\n                {\n                    stateData.AppendLine(\"State:\");\n                    SerializeStateToText(room.State, room.StateType, stateData, 1);\n                }\n                else\n                {\n                    stateData.AppendLine(\"State: null\");\n                }\n\n                EditorGUIUtility.systemCopyBuffer = stateData.ToString();\n                Debug.Log(\"Room state copied to clipboard!\");\n                EditorUtility.DisplayDialog(\"Copy State\", \"Room state has been copied to clipboard!\", \"OK\");\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to copy state: {ex.Message}\");\n                EditorUtility.DisplayDialog(\"Copy State\", $\"Failed to copy state:\\n{ex.Message}\", \"OK\");\n            }\n        }\n\n        private void SerializeStateToText(object obj, System.Type type, System.Text.StringBuilder sb, int indent)\n        {\n            if (obj == null || indent > 10)\n            {\n                return;\n            }\n\n            var indentStr = new string(' ', indent * 2);\n            var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance)\n                .Where(f => f.GetCustomAttribute<Colyseus.Schema.Type>() != null)\n                .OrderBy(f => f.GetCustomAttribute<Colyseus.Schema.Type>().Index)\n                .ToList();\n\n            foreach (var field in fields)\n            {\n                var fieldValue = field.GetValue(obj);\n                var fieldType = field.FieldType;\n\n                if (IsPrimitiveOrString(fieldType))\n                {\n                    sb.AppendLine($\"{indentStr}{field.Name}: {fieldValue ?? \"null\"}\");\n                }\n                else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(MapSchema<>))\n                {\n                    var itemsProperty = fieldType.GetField(\"items\");\n                    var itemsValue = itemsProperty?.GetValue(fieldValue);\n                    var enumerable = itemsValue as IDictionary;\n                    var count = enumerable?.Count ?? 0;\n                    sb.AppendLine($\"{indentStr}{field.Name} (MapSchema): {count} items\");\n\n                    if (enumerable != null && count > 0)\n                    {\n                        foreach (DictionaryEntry kvp in enumerable)\n                        {\n                            var key = kvp.Key?.ToString() ?? \"null\";\n                            sb.AppendLine($\"{indentStr}  [{key}]:\");\n                            if (kvp.Value != null && typeof(Schema.Schema).IsAssignableFrom(kvp.Value.GetType()))\n                            {\n                                SerializeStateToText(kvp.Value, kvp.Value.GetType(), sb, indent + 2);\n                            }\n                            else\n                            {\n                                sb.AppendLine($\"{indentStr}    {kvp.Value}\");\n                            }\n                        }\n                    }\n                }\n                else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(ArraySchema<>))\n                {\n                    var enumerable = fieldValue as IEnumerable;\n                    var countProp = fieldType.GetProperty(\"Count\");\n                    var count = countProp?.GetValue(fieldValue) as int? ?? 0;\n                    sb.AppendLine($\"{indentStr}{field.Name} (ArraySchema): {count} items\");\n\n                    if (enumerable != null && count > 0)\n                    {\n                        var index = 0;\n                        foreach (var item in enumerable)\n                        {\n                            sb.AppendLine($\"{indentStr}  [{index}]:\");\n                            if (item != null && typeof(Schema.Schema).IsAssignableFrom(item.GetType()))\n                            {\n                                SerializeStateToText(item, item.GetType(), sb, indent + 2);\n                            }\n                            else\n                            {\n                                sb.AppendLine($\"{indentStr}    {item}\");\n                            }\n                            index++;\n                        }\n                    }\n                }\n                else if (typeof(Schema.Schema).IsAssignableFrom(fieldType))\n                {\n                    sb.AppendLine($\"{indentStr}{field.Name} ({fieldType.Name}):\");\n                    if (fieldValue != null)\n                    {\n                        SerializeStateToText(fieldValue, fieldType, sb, indent + 1);\n                    }\n                    else\n                    {\n                        sb.AppendLine($\"{indentStr}  null\");\n                    }\n                }\n            }\n        }\n\n        private void DrawRoomContent(RoomInfo roomInfo)\n        {\n            // Room Information Section\n            DrawSection(\"Connection Info\", () =>\n            {\n                DrawReadOnlyField(\"Room ID\", roomInfo.RoomId ?? \"N/A\");\n                DrawReadOnlyField(\"Session ID\", roomInfo.SessionId ?? \"N/A\");\n                DrawReadOnlyField(\"Status\", roomInfo.IsConnected ? \"Connected\" : \"Disconnected\");\n                DrawReadOnlyObjectField(\"Source Object\", roomInfo.SourceObject, typeof(MonoBehaviour));\n\n                EditorGUILayout.Space(5);\n\n                // Leave/Drop buttons\n                EditorGUILayout.BeginHorizontal();\n                EditorGUI.BeginDisabledGroup(!roomInfo.IsConnected);\n\n                if (GUILayout.Button(\"Leave\", GUILayout.Height(24)))\n                {\n                    LeaveRoom(roomInfo, consented: true);\n                }\n\n                if (GUILayout.Button(\"Drop\", GUILayout.Height(24)))\n                {\n                    DropRoom(roomInfo);\n                }\n\n                EditorGUI.EndDisabledGroup();\n                EditorGUILayout.EndHorizontal();\n            });\n\n            EditorGUILayout.Space(5);\n\n            // Draw horizontal split panel for State and Messages\n            DrawStateAndMessagesSplitPanel(roomInfo);\n        }\n\n        private void DrawSection(string title, Action content)\n        {\n            var foldoutKey = $\"section_{title}_{EditorGUI.indentLevel}\";\n            if (!_foldouts.ContainsKey(foldoutKey))\n            {\n                _foldouts[foldoutKey] = true;\n            }\n\n            _foldouts[foldoutKey] = EditorGUILayout.Foldout(_foldouts[foldoutKey], title, true, EditorStyles.foldoutHeader);\n\n            if (_foldouts[foldoutKey])\n            {\n                EditorGUI.indentLevel++;\n                content?.Invoke();\n                EditorGUI.indentLevel--;\n            }\n        }\n\n        private void DrawSchemaObject(object obj, System.Type type, string path, int depth = 0)\n        {\n            if (obj == null || depth > 10) // Prevent infinite recursion\n            {\n                EditorGUILayout.LabelField(\"null\", EditorStyles.miniLabel);\n                return;\n            }\n\n            var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance)\n                .Where(f => f.GetCustomAttribute<Colyseus.Schema.Type>() != null)\n                .OrderBy(f => f.GetCustomAttribute<Colyseus.Schema.Type>().Index)\n                .ToList();\n\n            foreach (var field in fields)\n            {\n                var fieldValue = field.GetValue(obj);\n                var fieldType = field.FieldType;\n                var fieldPath = $\"{path}.{field.Name}\";\n\n                // Handle different field types\n                if (IsPrimitiveOrString(fieldType))\n                {\n                    DrawReadOnlyField(field.Name, fieldValue?.ToString() ?? \"null\");\n                }\n                else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(MapSchema<>))\n                {\n                    DrawMapSchema(field.Name, fieldValue, fieldPath, depth);\n                }\n                else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(ArraySchema<>))\n                {\n                    DrawArraySchema(field.Name, fieldValue, fieldPath, depth);\n                }\n                else if (typeof(Schema.Schema).IsAssignableFrom(fieldType))\n                {\n                    DrawNestedSchema(field.Name, fieldValue, fieldType, fieldPath, depth);\n                }\n                else\n                {\n                    DrawReadOnlyField(field.Name, $\"<{fieldType.Name}>\");\n                }\n            }\n        }\n\n        private void DrawMapSchema(string fieldName, object mapObj, string path, int depth)\n        {\n            var foldoutKey = $\"map_{path}\";\n            if (!_foldouts.ContainsKey(foldoutKey))\n            {\n                _foldouts[foldoutKey] = true; // Expand by default\n            }\n\n            if (mapObj == null)\n            {\n                DrawReadOnlyField(fieldName, \"null (MapSchema)\");\n                return;\n            }\n\n            var mapType = mapObj.GetType();\n            var countProp = mapType.GetProperty(\"Count\");\n            var count = countProp?.GetValue(mapObj) as int? ?? 0;\n\n            _foldouts[foldoutKey] = EditorGUILayout.Foldout(\n                _foldouts[foldoutKey],\n                $\"{fieldName} (MapSchema) [{count} items]\",\n                true\n            );\n\n            if (_foldouts[foldoutKey])\n            {\n                EditorGUI.indentLevel++;\n\n                if (count == 0)\n                {\n                    EditorGUILayout.LabelField(\"(empty)\", EditorStyles.miniLabel);\n                }\n                else\n                {\n                    // Access the items property of MapSchema\n                    var itemsProperty = mapType.GetField(\"items\");\n                    var itemsValue = itemsProperty?.GetValue(mapObj);\n                    var enumerable = itemsValue as IDictionary;\n\n                    if (enumerable != null)\n                    {\n                        var index = 0;\n                        foreach (DictionaryEntry kvp in enumerable)\n                        {\n                            var key = kvp.Key?.ToString() ?? \"null\";\n                            var value = kvp.Value;\n                            var itemPath = $\"{path}[{key}]\";\n\n                            if (value != null && typeof(Schema.Schema).IsAssignableFrom(value.GetType()))\n                            {\n                                DrawNestedSchema($\"[{key}]\", value, value.GetType(), itemPath, depth + 1);\n                            }\n                            else\n                            {\n                                DrawReadOnlyField($\"[{key}]\", value?.ToString() ?? \"null\");\n                            }\n\n                            index++;\n                            if (index > 100) // Limit display to prevent performance issues\n                            {\n                                EditorGUILayout.LabelField($\"... and {count - 100} more items\", EditorStyles.miniLabel);\n                                break;\n                            }\n                        }\n                    }\n                    else\n                    {\n                        EditorGUILayout.LabelField($\"Error: Could not access MapSchema items\", EditorStyles.miniLabel);\n                    }\n                }\n\n                EditorGUI.indentLevel--;\n            }\n        }\n\n        private void DrawArraySchema(string fieldName, object arrayObj, string path, int depth)\n        {\n            var foldoutKey = $\"array_{path}\";\n            if (!_foldouts.ContainsKey(foldoutKey))\n            {\n                _foldouts[foldoutKey] = true; // Expand by default\n            }\n\n            if (arrayObj == null)\n            {\n                DrawReadOnlyField(fieldName, \"null (ArraySchema)\");\n                return;\n            }\n\n            var arrayType = arrayObj.GetType();\n            var countProp = arrayType.GetProperty(\"Count\");\n            var count = countProp?.GetValue(arrayObj) as int? ?? 0;\n\n            _foldouts[foldoutKey] = EditorGUILayout.Foldout(\n                _foldouts[foldoutKey],\n                $\"{fieldName} (ArraySchema) [{count} items]\",\n                true\n            );\n\n            if (_foldouts[foldoutKey])\n            {\n                EditorGUI.indentLevel++;\n\n                if (count == 0)\n                {\n                    EditorGUILayout.LabelField(\"(empty)\", EditorStyles.miniLabel);\n                }\n                else\n                {\n                    // Access the items field of ArraySchema (which is a List<T>)\n                    var itemsField = arrayType.GetField(\"items\");\n                    var itemsValue = itemsField?.GetValue(arrayObj);\n                    var enumerable = itemsValue as IList;\n\n                    if (enumerable != null)\n                    {\n                        var index = 0;\n                        foreach (var item in enumerable)\n                        {\n                            var itemPath = $\"{path}[{index}]\";\n\n                            if (item != null && typeof(Schema.Schema).IsAssignableFrom(item.GetType()))\n                            {\n                                DrawNestedSchema($\"[{index}]\", item, item.GetType(), itemPath, depth + 1);\n                            }\n                            else\n                            {\n                                DrawReadOnlyField($\"[{index}]\", item?.ToString() ?? \"null\");\n                            }\n\n                            index++;\n                            if (index > 100) // Limit display to prevent performance issues\n                            {\n                                EditorGUILayout.LabelField($\"... and {count - 100} more items\", EditorStyles.miniLabel);\n                                break;\n                            }\n                        }\n                    }\n                    else\n                    {\n                        EditorGUILayout.LabelField($\"Error: Could not access ArraySchema items\", EditorStyles.miniLabel);\n                    }\n                }\n\n                EditorGUI.indentLevel--;\n            }\n        }\n\n        private void DrawNestedSchema(string fieldName, object schemaObj, System.Type schemaType, string path, int depth)\n        {\n            var foldoutKey = $\"schema_{path}\";\n            if (!_foldouts.ContainsKey(foldoutKey))\n            {\n                _foldouts[foldoutKey] = false; // Collapsed by default for nested schemas\n            }\n\n            if (schemaObj == null)\n            {\n                DrawReadOnlyField(fieldName, $\"null ({schemaType.Name})\");\n                return;\n            }\n\n            _foldouts[foldoutKey] = EditorGUILayout.Foldout(\n                _foldouts[foldoutKey],\n                $\"{fieldName} ({schemaType.Name})\",\n                true\n            );\n\n            if (_foldouts[foldoutKey])\n            {\n                EditorGUI.indentLevel++;\n                DrawSchemaObject(schemaObj, schemaType, path, depth + 1);\n                EditorGUI.indentLevel--;\n            }\n        }\n\n        private void DrawReadOnlyField(string label, string value)\n        {\n            EditorGUILayout.BeginHorizontal();\n            EditorGUILayout.LabelField(label, GUILayout.Width(EditorGUIUtility.labelWidth - 20));\n            EditorGUILayout.SelectableLabel(value, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));\n            EditorGUILayout.EndHorizontal();\n        }\n\n        private void DrawReadOnlyObjectField(string label, UnityEngine.Object obj, System.Type type)\n        {\n            EditorGUILayout.BeginHorizontal();\n            EditorGUILayout.LabelField(label, GUILayout.Width(EditorGUIUtility.labelWidth - 20));\n            EditorGUI.BeginDisabledGroup(true);\n            EditorGUILayout.ObjectField(obj, type, true);\n            EditorGUI.EndDisabledGroup();\n            EditorGUILayout.EndHorizontal();\n        }\n\n        private bool IsPrimitiveOrString(System.Type type)\n        {\n            return type.IsPrimitive || type == typeof(string) || type == typeof(decimal) ||\n                   type.IsEnum || type == typeof(DateTime);\n        }\n\n        private List<RoomInfo> FindAllColyseusRooms()\n        {\n            var roomInfos = new List<RoomInfo>();\n            var processedRooms = new HashSet<object>(); // Avoid duplicates\n\n            if (!Application.isPlaying)\n            {\n                return roomInfos;\n            }\n\n            // Find all MonoBehaviours in the scene\n            var allMonoBehaviours = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);\n\n            foreach (var behaviour in allMonoBehaviours)\n            {\n                if (behaviour == null) continue;\n\n                var behaviourType = behaviour.GetType();\n\n                // Check instance fields\n                var instanceFields = behaviourType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);\n                foreach (var field in instanceFields)\n                {\n                    if (IsColyseusRoomType(field.FieldType))\n                    {\n                        var roomObj = field.GetValue(behaviour);\n                        if (roomObj != null && !processedRooms.Contains(roomObj))\n                        {\n                            processedRooms.Add(roomObj);\n                            var roomInfo = ExtractRoomInfo(roomObj, field.FieldType, behaviour);\n                            if (roomInfo != null)\n                            {\n                                roomInfos.Add(roomInfo);\n                            }\n                        }\n                    }\n                }\n\n                // Check static fields\n                var staticFields = behaviourType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);\n                foreach (var field in staticFields)\n                {\n                    if (IsColyseusRoomType(field.FieldType))\n                    {\n                        var roomObj = field.GetValue(null); // null for static fields\n                        if (roomObj != null && !processedRooms.Contains(roomObj))\n                        {\n                            processedRooms.Add(roomObj);\n                            var roomInfo = ExtractRoomInfo(roomObj, field.FieldType, behaviour);\n                            if (roomInfo != null)\n                            {\n                                roomInfos.Add(roomInfo);\n                            }\n                        }\n                    }\n                }\n            }\n\n            return roomInfos;\n        }\n\n        private bool IsColyseusRoomType(System.Type type)\n        {\n            if (type == null) return false;\n\n            // Check if it's a generic Room<T>\n            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Room<>))\n            {\n                return true;\n            }\n\n            // Check if it implements IRoom\n            return typeof(IRoom).IsAssignableFrom(type);\n        }\n\n        private RoomInfo ExtractRoomInfo(object room, System.Type roomType, MonoBehaviour source)\n        {\n            try\n            {\n\n                var roomInfo = new RoomInfo\n                {\n                    SourceObject = source,\n                    RoomType = roomType,\n                    RoomInstance = room\n                };\n\n                // Get RoomId (field)\n                var roomIdField = roomType.GetField(\"RoomId\");\n                roomInfo.RoomId = roomIdField?.GetValue(room) as string;\n\n                // Get SessionId (field)\n                var sessionIdField = roomType.GetField(\"SessionId\");\n                roomInfo.SessionId = sessionIdField?.GetValue(room) as string;\n\n                // Get Name (field)\n                var nameField = roomType.GetField(\"Name\");\n                roomInfo.Name = nameField?.GetValue(room) as string;\n\n                // Get Connection status (field)\n                var connectionField = roomType.GetField(\"Connection\");\n                var connection = connectionField?.GetValue(room);\n                if (connection != null)\n                {\n                    var isOpenProp = connection.GetType().GetField(\"IsOpen\");\n                    roomInfo.IsConnected = (isOpenProp?.GetValue(connection) as bool?) ?? false;\n                }\n\n                // Get State (property)\n                var stateProp = roomType.GetProperty(\"State\");\n                roomInfo.State = stateProp?.GetValue(room);\n\n                if (roomInfo.State != null)\n                {\n                    roomInfo.StateType = roomInfo.State.GetType();\n                }\n\n                // Note: Room message type capture is now handled automatically\n                // via compile-time checks in Room.OnMessage()\n\n                return roomInfo;\n            }\n            catch (Exception ex)\n            {\n                Debug.LogWarning($\"Failed to extract room info: {ex.Message}\");\n                return null;\n            }\n        }\n\n\n\n        private void DrawStateAndMessagesSplitPanel(RoomInfo roomInfo)\n        {\n            var roomId = roomInfo.RoomId;\n            var splitterKey = $\"room_splitter_{roomId}\";\n\n            // Initialize splitter position for this room\n            if (!_roomSplitterPosition.ContainsKey(splitterKey))\n            {\n                _roomSplitterPosition[splitterKey] = 300f; // Default top panel height\n            }\n            if (!_isResizingRoomSplitter.ContainsKey(splitterKey))\n            {\n                _isResizingRoomSplitter[splitterKey] = false;\n            }\n\n            // Calculate available height (estimate remaining scroll view height)\n            var availableHeight = 600f; // Default available height\n            var topPanelHeight = Mathf.Clamp(_roomSplitterPosition[splitterKey], MinPanelHeight, availableHeight - MinPanelHeight - SplitterHeight);\n            var bottomPanelHeight = availableHeight - topPanelHeight - SplitterHeight;\n\n            // Top Panel - Room State\n            EditorGUILayout.BeginVertical(GUILayout.Height(topPanelHeight));\n            DrawStateSection(roomInfo);\n            EditorGUILayout.EndVertical();\n\n            // Horizontal Splitter\n            DrawHorizontalSplitter(splitterKey, availableHeight);\n\n            // Bottom Panel - Messages\n            EditorGUILayout.BeginVertical(GUILayout.Height(bottomPanelHeight));\n            DrawMessagesSection(roomInfo);\n            EditorGUILayout.EndVertical();\n        }\n\n        private void DrawHorizontalSplitter(string splitterKey, float availableHeight)\n        {\n            var splitterRect = EditorGUILayout.GetControlRect(GUILayout.Height(SplitterHeight), GUILayout.ExpandWidth(true));\n            EditorGUI.DrawRect(splitterRect, new Color(0.3f, 0.3f, 0.3f, 0.5f));\n            EditorGUIUtility.AddCursorRect(splitterRect, MouseCursor.ResizeVertical);\n\n            var e = Event.current;\n\n            if (e.type == EventType.MouseDown && splitterRect.Contains(e.mousePosition))\n            {\n                _isResizingRoomSplitter[splitterKey] = true;\n                e.Use();\n            }\n\n            if (_isResizingRoomSplitter[splitterKey])\n            {\n                if (e.type == EventType.MouseDrag)\n                {\n                    _roomSplitterPosition[splitterKey] += e.delta.y;\n                    _roomSplitterPosition[splitterKey] = Mathf.Clamp(\n                        _roomSplitterPosition[splitterKey],\n                        MinPanelHeight,\n                        availableHeight - MinPanelHeight - SplitterHeight\n                    );\n                    Repaint();\n                    e.Use();\n                }\n\n                if (e.type == EventType.MouseUp)\n                {\n                    _isResizingRoomSplitter[splitterKey] = false;\n                    e.Use();\n                }\n            }\n        }\n\n        private void DrawStateSection(RoomInfo roomInfo)\n        {\n            var stateScrollKey = $\"state_scroll_{roomInfo.RoomId}\";\n            if (!_foldouts.ContainsKey(stateScrollKey))\n            {\n                _foldouts[stateScrollKey] = true;\n            }\n\n            DrawSection(\"Room State\", () =>\n            {\n                if (roomInfo.State != null)\n                {\n                    DrawReadOnlyField(\"State Type\", roomInfo.StateType?.Name ?? \"Unknown\");\n                    EditorGUILayout.Space(3);\n                    DrawSchemaObject(roomInfo.State, roomInfo.StateType, \"state\");\n                }\n                else\n                {\n                    EditorGUILayout.HelpBox(\"State is null or not yet initialized\", MessageType.Warning);\n                }\n            });\n        }\n\n        private void DrawMessagesSection(RoomInfo roomInfo)\n        {\n            var roomId = roomInfo.RoomId;\n            if (string.IsNullOrEmpty(roomId))\n            {\n                return;\n            }\n\n            DrawSection(\"Messages\", () =>\n            {\n                // Access message types from static capture\n                if (!RoomMessageType.CapturedMessageTypes.ContainsKey(roomId) ||\n                    RoomMessageType.CapturedMessageTypes[roomId] == null ||\n                    RoomMessageType.CapturedMessageTypes[roomId].Count == 0)\n                {\n                    EditorGUILayout.HelpBox(\n                        \"No message types available.\\n\\n\" +\n                        \"Waiting for '__playground_message_types' message from server.\",\n                        MessageType.Info\n                    );\n                    return;\n                }\n\n                if (!_messageInputs.ContainsKey(roomId))\n                {\n                    _messageInputs[roomId] = new Dictionary<string, string>();\n                }\n\n                if (!_selectedMessageTypeIndex.ContainsKey(roomId))\n                {\n                    _selectedMessageTypeIndex[roomId] = 0;\n                }\n\n                var messageTypes = RoomMessageType.CapturedMessageTypes[roomId];\n                var messageInputs = _messageInputs[roomId];\n\n                // Create array of message type names for popup\n                var messageTypeList = messageTypes.Keys.ToList();\n                messageTypeList.Add(\"* (Custom)\");\n                var messageTypeNames = messageTypeList.ToArray();\n\n                if (messageTypeNames.Length == 0)\n                {\n                    EditorGUILayout.HelpBox(\"No message types available. Enable playground in the server to see message types here.\", MessageType.Info);\n                    return;\n                }\n\n                // Ensure index is valid\n                if (_selectedMessageTypeIndex[roomId] >= messageTypeNames.Length)\n                {\n                    _selectedMessageTypeIndex[roomId] = 0;\n                }\n\n                // Draw message interface\n                DrawMessageInterface(roomInfo, messageTypeNames, messageTypes, messageInputs);\n            });\n        }\n\n        private void DrawMessageInterface(RoomInfo roomInfo, string[] messageTypeNames, Dictionary<string, object> messageTypes, Dictionary<string, string> messageInputs)\n        {\n            var roomId = roomInfo.RoomId;\n\n            // Message type selector\n            EditorGUILayout.LabelField(\"Message Type:\", EditorStyles.boldLabel);\n            var previousIndex = _selectedMessageTypeIndex[roomId];\n            _selectedMessageTypeIndex[roomId] = EditorGUILayout.Popup(\n                _selectedMessageTypeIndex[roomId],\n                messageTypeNames,\n                GUILayout.Height(20)\n            );\n\n            var selectedMessageName = messageTypeNames[_selectedMessageTypeIndex[roomId]];\n            var isCustomMessage = selectedMessageName == \"* (Custom)\";\n\n            // Handle custom message type\n            if (isCustomMessage)\n            {\n                var customKey = $\"{roomId}_custom\";\n                if (!_customMessageTypes.ContainsKey(customKey))\n                {\n                    _customMessageTypes[customKey] = \"\";\n                }\n\n                EditorGUILayout.Space(4);\n                EditorGUILayout.LabelField(\"Custom Message Type:\", EditorStyles.boldLabel);\n                _customMessageTypes[customKey] = EditorGUILayout.TextField(_customMessageTypes[customKey], GUILayout.Height(20));\n\n                selectedMessageName = _customMessageTypes[customKey];\n            }\n\n            IDictionary messageSchema = !isCustomMessage && messageTypes.ContainsKey(selectedMessageName)\n                ? messageTypes[selectedMessageName] as IDictionary\n                : null;\n\n            EditorGUILayout.Space(4);\n\n            // Initialize raw JSON toggle state\n            var rawJsonKey = $\"{roomId}_{selectedMessageName}\";\n            if (!_useRawJson.ContainsKey(rawJsonKey))\n            {\n                _useRawJson[rawJsonKey] = false;\n            }\n\n            // Initialize raw JSON input\n            if (!_rawJsonInputs.ContainsKey(rawJsonKey))\n            {\n                _rawJsonInputs[rawJsonKey] = messageSchema != null ? GenerateDefaultJSON(messageSchema) : \"{}\";\n            }\n\n            // Check if message type changed - update raw JSON when switching message types\n            var currentMessageKey = isCustomMessage ? \"* (Custom)\" : selectedMessageName;\n            if (!_lastSelectedMessageType.ContainsKey(roomId) ||\n                _lastSelectedMessageType[roomId] != currentMessageKey)\n            {\n                _lastSelectedMessageType[roomId] = currentMessageKey;\n                _rawJsonInputs[rawJsonKey] = messageSchema != null ? GenerateDefaultJSON(messageSchema) : \"{}\";\n\n                // Clear all field inputs for this message type\n                if (!isCustomMessage)\n                {\n                    var keysToRemove = messageInputs.Keys.Where(k => k.StartsWith($\"{roomId}_{selectedMessageName}_field_\")).ToList();\n                    foreach (var key in keysToRemove)\n                    {\n                        messageInputs.Remove(key);\n                    }\n                }\n            }\n\n            // Toggle between form fields and raw JSON\n            var previousUseRawJson = _useRawJson[rawJsonKey];\n\n            // Only show toggle if schema is available\n            if (messageSchema != null)\n            {\n                _useRawJson[rawJsonKey] = EditorGUILayout.Toggle(\"Use Raw JSON\", _useRawJson[rawJsonKey]);\n                EditorGUILayout.Space(4);\n            }\n\n            // When switching to raw JSON mode, populate from field values\n            if (_useRawJson[rawJsonKey] && !previousUseRawJson && messageSchema != null)\n            {\n                _rawJsonInputs[rawJsonKey] = GenerateJSONFromFields(roomId, selectedMessageName, messageSchema, messageInputs);\n            }\n\n            // If raw JSON mode is enabled or schema is invalid, show JSON text area\n            if (_useRawJson[rawJsonKey] || messageSchema == null)\n            {\n                EditorGUILayout.Space(4);\n                EditorGUILayout.LabelField(\"JSON Payload:\", EditorStyles.boldLabel);\n\n                // Multi-line text area for JSON input\n                EditorGUILayout.BeginVertical(EditorStyles.helpBox);\n                var textAreaStyle = new GUIStyle(EditorStyles.textArea);\n                textAreaStyle.wordWrap = true;\n                textAreaStyle.stretchHeight = true;\n\n                _rawJsonInputs[rawJsonKey] = EditorGUILayout.TextArea(\n                    _rawJsonInputs[rawJsonKey],\n                    textAreaStyle,\n                    GUILayout.MinHeight(40),\n                    GUILayout.MaxHeight(80)\n                );\n                EditorGUILayout.EndVertical();\n            }\n            else\n            {\n                // Get required fields\n                List<object> requiredFields = null;\n                if (messageSchema.Contains(\"required\"))\n                {\n                    requiredFields = messageSchema[\"required\"] as List<object>;\n                }\n\n                // Draw individual field inputs\n                if (messageSchema.Contains(\"properties\"))\n                {\n                    var properties = messageSchema[\"properties\"] as IDictionary;\n                    if (properties != null && properties.Count > 0)\n                    {\n                        EditorGUILayout.LabelField(\"Payload:\", EditorStyles.boldLabel);\n                        EditorGUI.indentLevel++;\n\n                        foreach (DictionaryEntry prop in properties)\n                        {\n                            var propName = prop.Key as string;\n                            var propSchema = prop.Value as IDictionary;\n\n                            if (propSchema != null && propSchema.Contains(\"type\"))\n                            {\n                                var isRequired = requiredFields != null && requiredFields.Any(r => r.ToString() == propName);\n                                DrawMessageField(roomId, selectedMessageName, propName, propSchema, isRequired, messageInputs);\n                            }\n                        }\n\n                        EditorGUI.indentLevel--;\n                    }\n                }\n                else\n                {\n                    EditorGUILayout.HelpBox(\"No fields defined for this message type.\", MessageType.Info);\n                }\n            }\n\n            EditorGUILayout.Space(8);\n\n            // Send button\n            var canSend = !isCustomMessage || !string.IsNullOrWhiteSpace(selectedMessageName);\n            var buttonLabel = isCustomMessage && string.IsNullOrWhiteSpace(selectedMessageName)\n                ? \"Send (enter message type above)\"\n                : $\"Send '{selectedMessageName}'\";\n\n            EditorGUI.BeginDisabledGroup(!canSend);\n            if (GUILayout.Button(buttonLabel, GUILayout.Height(30)))\n            {\n                // Use raw JSON when explicitly enabled OR when messageSchema is null\n                if (_useRawJson[rawJsonKey] || messageSchema == null)\n                {\n                    SendMessageFromRawJson(roomInfo, selectedMessageName, _rawJsonInputs[rawJsonKey]);\n                }\n                else\n                {\n                    SendMessageFromFields(roomInfo, selectedMessageName, messageSchema, messageInputs);\n                }\n            }\n            EditorGUI.EndDisabledGroup();\n        }\n\n        private void DrawMessageField(string roomId, string messageName, string fieldName, IDictionary fieldSchema, bool isRequired, Dictionary<string, string> messageInputs)\n        {\n            var fieldKey = $\"{roomId}_{messageName}_field_{fieldName}\";\n            var fieldType = fieldSchema[\"type\"] as string;\n\n            // Initialize with default value if not exists\n            if (!messageInputs.ContainsKey(fieldKey))\n            {\n                messageInputs[fieldKey] = GetDefaultValueForType(fieldSchema);\n            }\n\n            // Create label with asterisk for required fields\n            var label = isRequired ? $\"{fieldName} *\" : fieldName;\n\n            // Add description as tooltip if available\n            GUIContent labelContent;\n            if (fieldSchema.Contains(\"description\"))\n            {\n                var description = fieldSchema[\"description\"].ToString();\n                labelContent = new GUIContent(label, description);\n            }\n            else\n            {\n                labelContent = new GUIContent(label);\n            }\n\n            EditorGUILayout.BeginHorizontal();\n            EditorGUILayout.LabelField(labelContent, GUILayout.Width(EditorGUIUtility.labelWidth - 20));\n\n            // Draw appropriate input control based on field type\n            switch (fieldType)\n            {\n                case \"boolean\":\n                    var boolValue = messageInputs[fieldKey] == \"true\";\n                    boolValue = EditorGUILayout.Toggle(boolValue);\n                    messageInputs[fieldKey] = boolValue.ToString().ToLower();\n                    break;\n\n                case \"integer\":\n                    if (int.TryParse(messageInputs[fieldKey], out int intValue))\n                    {\n                        intValue = EditorGUILayout.IntField(intValue);\n                        messageInputs[fieldKey] = intValue.ToString();\n                    }\n                    else\n                    {\n                        messageInputs[fieldKey] = EditorGUILayout.TextField(messageInputs[fieldKey]);\n                    }\n                    break;\n\n                case \"number\":\n                    if (float.TryParse(messageInputs[fieldKey], out float floatValue))\n                    {\n                        floatValue = EditorGUILayout.FloatField(floatValue);\n                        messageInputs[fieldKey] = floatValue.ToString();\n                    }\n                    else\n                    {\n                        messageInputs[fieldKey] = EditorGUILayout.TextField(messageInputs[fieldKey]);\n                    }\n                    break;\n\n                case \"string\":\n                    // Remove quotes if present for display\n                    var stringValue = messageInputs[fieldKey];\n                    if (stringValue.StartsWith(\"\\\"\") && stringValue.EndsWith(\"\\\"\"))\n                    {\n                        stringValue = stringValue.Substring(1, stringValue.Length - 2);\n                    }\n                    stringValue = EditorGUILayout.TextField(stringValue);\n                    messageInputs[fieldKey] = stringValue;\n                    break;\n\n                case \"array\":\n                case \"object\":\n                    // For complex types, use a text field with JSON\n                    EditorGUILayout.LabelField($\"({fieldType})\", GUILayout.Width(60));\n                    messageInputs[fieldKey] = EditorGUILayout.TextField(messageInputs[fieldKey]);\n                    break;\n\n                default:\n                    messageInputs[fieldKey] = EditorGUILayout.TextField(messageInputs[fieldKey]);\n                    break;\n            }\n\n            EditorGUILayout.EndHorizontal();\n        }\n\n        private void SendMessageFromFields(RoomInfo roomInfo, string messageName, IDictionary messageSchema, Dictionary<string, string> messageInputs)\n        {\n            try\n            {\n                var roomId = roomInfo.RoomId;\n                var messageData = new Dictionary<string, object>();\n\n                // Build message object from field values\n                if (messageSchema.Contains(\"properties\"))\n                {\n                    var properties = messageSchema[\"properties\"] as IDictionary;\n                    if (properties != null)\n                    {\n                        foreach (DictionaryEntry prop in properties)\n                        {\n                            var propName = prop.Key as string;\n                            var propSchema = prop.Value as IDictionary;\n                            if (propSchema == null || !propSchema.Contains(\"type\")) continue;\n\n                            var fieldKey = $\"{roomId}_{messageName}_field_{propName}\";\n                            if (!messageInputs.ContainsKey(fieldKey)) continue;\n\n                            var fieldValue = messageInputs[fieldKey];\n                            var fieldType = propSchema[\"type\"] as string;\n\n                            // Convert field value to appropriate type\n                            object typedValue = ConvertFieldValue(fieldValue, fieldType);\n                            messageData[propName] = typedValue;\n                        }\n                    }\n                }\n\n                // Get the Send method from the room\n                var sendMethod = roomInfo.RoomType.GetMethod(\"Send\", new[] { typeof(string), typeof(object) });\n                if (sendMethod == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Failed to find Send method on room.\", \"OK\");\n                    return;\n                }\n\n                // Invoke Send method\n                var task = sendMethod.Invoke(roomInfo.RoomInstance, new object[] { messageName, messageData }) as System.Threading.Tasks.Task;\n                if (task != null)\n                {\n                    // Note: We can't await in a non-async void method, but the task will execute\n                    Debug.Log($\"Message '{messageName}' sent\");\n                }\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to send message '{messageName}': {ex.Message}\\n{ex.StackTrace}\");\n                EditorUtility.DisplayDialog(\"Error\", $\"Failed to send message:\\n{ex.Message}\", \"OK\");\n            }\n        }\n\n        private void LeaveRoom(RoomInfo roomInfo, bool consented)\n        {\n            try\n            {\n                // Get the Leave method from the room (with bool parameter)\n                var leaveMethod = roomInfo.RoomType.GetMethod(\"Leave\", new[] { typeof(bool) });\n                if (leaveMethod == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Failed to find Leave method on room.\", \"OK\");\n                    return;\n                }\n\n                // Invoke Leave method\n                var task = leaveMethod.Invoke(roomInfo.RoomInstance, new object[] { consented }) as System.Threading.Tasks.Task;\n                if (task != null)\n                {\n                    Debug.Log($\"Room '{roomInfo.Name}' - Leave requested\");\n                }\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to leave room: {ex.Message}\\n{ex.StackTrace}\");\n                EditorUtility.DisplayDialog(\"Error\", $\"Failed to leave room:\\n{ex.Message}\", \"OK\");\n            }\n        }\n\n        private void DropRoom(RoomInfo roomInfo)\n        {\n            try\n            {\n                // Get the Connection field from the room\n                var connectionField = roomInfo.RoomType.GetField(\"Connection\");\n                if (connectionField == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Failed to find Connection field on room.\", \"OK\");\n                    return;\n                }\n\n                var connection = connectionField.GetValue(roomInfo.RoomInstance);\n                if (connection == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Connection is null.\", \"OK\");\n                    return;\n                }\n\n                // Get the Drop method from the connection\n                var dropMethod = connection.GetType().GetMethod(\"Drop\");\n                if (dropMethod == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Failed to find Drop method on connection.\", \"OK\");\n                    return;\n                }\n\n                // Invoke Drop method\n                dropMethod.Invoke(connection, null);\n                Debug.Log($\"Room '{roomInfo.Name}' - Connection dropped\");\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to drop room connection: {ex.Message}\\n{ex.StackTrace}\");\n                EditorUtility.DisplayDialog(\"Error\", $\"Failed to drop connection:\\n{ex.Message}\", \"OK\");\n            }\n        }\n\n        private void SendMessageFromRawJson(RoomInfo roomInfo, string messageName, string jsonData)\n        {\n            try\n            {\n                // Parse JSON to object\n                object messageData;\n                try\n                {\n                    messageData = Json.Deserialize(typeof(Dictionary<string, object>), jsonData);\n                }\n                catch (Exception jsonEx)\n                {\n                    EditorUtility.DisplayDialog(\"JSON Parse Error\", $\"Failed to parse JSON:\\n{jsonEx.Message}\", \"OK\");\n                    Debug.LogError($\"JSON parse error: {jsonEx.Message}\\n{jsonData}\");\n                    return;\n                }\n\n                // Get the Send method from the room\n                var sendMethod = roomInfo.RoomType.GetMethod(\"Send\", new[] { typeof(string), typeof(object) });\n                if (sendMethod == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Failed to find Send method on room.\", \"OK\");\n                    return;\n                }\n\n                // Invoke Send method\n                var task = sendMethod.Invoke(roomInfo.RoomInstance, new object[] { messageName, messageData }) as System.Threading.Tasks.Task;\n                if (task != null)\n                {\n                    Debug.Log($\"Message '{messageName}' sent with raw JSON\");\n                }\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to send message '{messageName}': {ex.Message}\\n{ex.StackTrace}\");\n                EditorUtility.DisplayDialog(\"Error\", $\"Failed to send message:\\n{ex.Message}\", \"OK\");\n            }\n        }\n\n        private object ConvertFieldValue(string fieldValue, string fieldType)\n        {\n            switch (fieldType)\n            {\n                case \"boolean\":\n                    return fieldValue == \"true\";\n\n                case \"integer\":\n                    if (int.TryParse(fieldValue, out int intValue))\n                        return intValue;\n                    return 0;\n\n                case \"number\":\n                    if (double.TryParse(fieldValue, out double doubleValue))\n                        return doubleValue;\n                    return 0.0;\n\n                case \"string\":\n                    return fieldValue;\n\n                case \"array\":\n                    try\n                    {\n                        return Json.Deserialize(typeof(List<object>), fieldValue);\n                    }\n                    catch\n                    {\n                        return new List<object>();\n                    }\n\n                case \"object\":\n                    try\n                    {\n                        return Json.Deserialize(typeof(Dictionary<string, object>), fieldValue);\n                    }\n                    catch\n                    {\n                        return new Dictionary<string, object>();\n                    }\n\n                default:\n                    return fieldValue;\n            }\n        }\n\n        private string GenerateDefaultJSON(IDictionary schema)\n        {\n            try\n            {\n                if (!schema.Contains(\"properties\"))\n                {\n                    return \"{}\";\n                }\n\n                var properties = schema[\"properties\"] as IDictionary;\n                if (properties == null || properties.Count == 0)\n                {\n                    return \"{}\";\n                }\n\n                var sb = new StringBuilder();\n                sb.AppendLine(\"{\");\n\n                var propCount = 0;\n                foreach (DictionaryEntry prop in properties)\n                {\n                    var propName = prop.Key as string;\n                    var propSchema = prop.Value as IDictionary;\n                    if (propSchema == null) continue;\n\n                    sb.Append($\"  \\\"{propName}\\\": \");\n\n                    var defaultValue = GetDefaultValueForType(propSchema);\n                    sb.Append(defaultValue);\n\n                    propCount++;\n                    if (propCount < properties.Count)\n                    {\n                        sb.AppendLine(\",\");\n                    }\n                    else\n                    {\n                        sb.AppendLine();\n                    }\n                }\n\n                sb.Append(\"}\");\n                return sb.ToString();\n            }\n            catch (Exception ex)\n            {\n                Debug.LogWarning($\"Failed to generate default JSON: {ex.Message}\");\n                return \"{}\";\n            }\n        }\n\n        private string GetDefaultValueForType(IDictionary propSchema)\n        {\n            if (!propSchema.Contains(\"type\"))\n            {\n                return \"null\";\n            }\n\n            var type = propSchema[\"type\"] as string;\n            switch (type)\n            {\n                case \"string\":\n                    return \"\\\"\\\"\";\n                case \"number\":\n                case \"integer\":\n                    return \"0\";\n                case \"boolean\":\n                    return \"false\";\n                case \"array\":\n                    return \"[]\";\n                case \"object\":\n                    return \"{}\";\n                default:\n                    return \"null\";\n            }\n        }\n\n        private string GenerateJSONFromFields(string roomId, string messageName, IDictionary messageSchema, Dictionary<string, string> messageInputs)\n        {\n            try\n            {\n                if (!messageSchema.Contains(\"properties\"))\n                {\n                    return \"{}\";\n                }\n\n                var properties = messageSchema[\"properties\"] as IDictionary;\n                if (properties == null || properties.Count == 0)\n                {\n                    return \"{}\";\n                }\n\n                var sb = new StringBuilder();\n                sb.AppendLine(\"{\");\n\n                var propCount = 0;\n                var totalProps = properties.Count;\n\n                foreach (DictionaryEntry prop in properties)\n                {\n                    var propName = prop.Key as string;\n                    var propSchema = prop.Value as IDictionary;\n                    if (propSchema == null || !propSchema.Contains(\"type\")) continue;\n\n                    var fieldKey = $\"{roomId}_{messageName}_field_{propName}\";\n                    var fieldType = propSchema[\"type\"] as string;\n\n                    sb.Append($\"  \\\"{propName}\\\": \");\n\n                    // Get value from field input or use default\n                    string jsonValue;\n                    if (messageInputs.ContainsKey(fieldKey))\n                    {\n                        var fieldValue = messageInputs[fieldKey];\n                        jsonValue = ConvertFieldValueToJSON(fieldValue, fieldType);\n                    }\n                    else\n                    {\n                        jsonValue = GetDefaultValueForType(propSchema);\n                    }\n\n                    sb.Append(jsonValue);\n\n                    propCount++;\n                    if (propCount < totalProps)\n                    {\n                        sb.AppendLine(\",\");\n                    }\n                    else\n                    {\n                        sb.AppendLine();\n                    }\n                }\n\n                sb.Append(\"}\");\n                return sb.ToString();\n            }\n            catch (Exception ex)\n            {\n                Debug.LogWarning($\"Failed to generate JSON from fields: {ex.Message}\");\n                return GenerateDefaultJSON(messageSchema);\n            }\n        }\n\n        private string ConvertFieldValueToJSON(string fieldValue, string fieldType)\n        {\n            switch (fieldType)\n            {\n                case \"boolean\":\n                    return fieldValue == \"true\" ? \"true\" : \"false\";\n\n                case \"integer\":\n                    if (int.TryParse(fieldValue, out int intValue))\n                        return intValue.ToString();\n                    return \"0\";\n\n                case \"number\":\n                    if (double.TryParse(fieldValue, out double doubleValue))\n                        return doubleValue.ToString();\n                    return \"0\";\n\n                case \"string\":\n                    // Escape quotes and wrap in quotes\n                    var escaped = fieldValue.Replace(\"\\\\\", \"\\\\\\\\\").Replace(\"\\\"\", \"\\\\\\\"\");\n                    return $\"\\\"{ escaped}\\\"\";\n\n                case \"array\":\n                case \"object\":\n                    // Try to parse as JSON, otherwise treat as string\n                    try\n                    {\n                        var parsed = Json.Deserialize(typeof(object), fieldValue);\n                        return fieldValue; // If it parses, use as-is\n                    }\n                    catch\n                    {\n                        return fieldValue.StartsWith(\"[\") || fieldValue.StartsWith(\"{\") ? fieldValue : \"{}\";\n                    }\n\n                default:\n                    return $\"\\\"{fieldValue}\\\"\";\n            }\n        }\n\n        private async void SendMessage(RoomInfo roomInfo, string messageName, string jsonData)\n        {\n            try\n            {\n                // Parse JSON to object\n                var messageData = ParseJSON(jsonData);\n\n                // Get the Send method from the room\n                var sendMethod = roomInfo.RoomType.GetMethod(\"Send\", new[] { typeof(string), typeof(object) });\n                if (sendMethod == null)\n                {\n                    EditorUtility.DisplayDialog(\"Error\", \"Failed to find Send method on room.\", \"OK\");\n                    return;\n                }\n\n                // Invoke Send method\n                var task = sendMethod.Invoke(roomInfo.RoomInstance, new object[] { messageName, messageData }) as System.Threading.Tasks.Task;\n                if (task != null)\n                {\n                    await task;\n                    Debug.Log($\"Message '{messageName}' sent successfully!\");\n                }\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to send message '{messageName}': {ex.Message}\\n{ex.StackTrace}\");\n                EditorUtility.DisplayDialog(\"Error\", $\"Failed to send message:\\n{ex.Message}\", \"OK\");\n            }\n        }\n\n        private object ParseJSON(string json)\n        {\n            // Parse JSON using GameDevWare.Serialization.Json\n            try\n            {\n                return Json.Deserialize(typeof(Dictionary<string, object>), json);\n            }\n            catch (Exception ex)\n            {\n                Debug.LogError($\"Failed to parse JSON: {ex.Message}\");\n                throw;\n            }\n        }\n\n        private void DrawSchemaInfo(IDictionary schema)\n        {\n            if (schema == null)\n            {\n                EditorGUILayout.LabelField(\"No schema information available\", EditorStyles.miniLabel);\n                return;\n            }\n\n            // Display schema type\n            if (schema.Contains(\"type\"))\n            {\n                DrawReadOnlyField(\"Type\", schema[\"type\"].ToString());\n            }\n\n            // Display properties\n            if (schema.Contains(\"properties\"))\n            {\n                var properties = schema[\"properties\"] as IDictionary;\n                if (properties != null && properties.Count > 0)\n                {\n                    EditorGUILayout.LabelField(\"Properties:\", EditorStyles.boldLabel);\n                    EditorGUI.indentLevel++;\n\n                    foreach (DictionaryEntry prop in properties)\n                    {\n                        var propName = prop.Key as string;\n                        var propSchema = prop.Value as IDictionary;\n\n                        if (propSchema != null && propSchema.Contains(\"type\"))\n                        {\n                            var propType = propSchema[\"type\"].ToString();\n                            var propInfo = propType;\n\n                            // Add description if available\n                            if (propSchema.Contains(\"description\"))\n                            {\n                                propInfo += $\" - {propSchema[\"description\"]}\";\n                            }\n\n                            DrawReadOnlyField(propName, propInfo);\n                        }\n                    }\n\n                    EditorGUI.indentLevel--;\n                }\n            }\n\n            // Display required fields\n            if (schema.Contains(\"required\"))\n            {\n                var required = schema[\"required\"] as List<object>;\n                if (required != null && required.Count > 0)\n                {\n                    var requiredStr = string.Join(\", \", required.Select(r => r.ToString()));\n                    DrawReadOnlyField(\"Required\", requiredStr);\n                }\n            }\n        }\n\n        private class RoomInfo\n        {\n            public string RoomId;\n            public string SessionId;\n            public string Name;\n            public bool IsConnected;\n            public object State;\n            public System.Type StateType;\n            public System.Type RoomType;\n            public MonoBehaviour SourceObject;\n            public object RoomInstance;\n        }\n    }\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Editor/RoomInspector.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 7306c18ccdb7b40c78a54abc8f917b50"
  },
  {
    "path": "Assets/Colyseus/Editor.meta",
    "content": "fileFormatVersion: 2\nguid: 12db36416327a4e74873a275325fd6f5\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/LICENSE",
    "content": "Copyright (c) 2021 Lucid Sight\nCopyright (c) 2015-2021 Endel Dreyer\n\nMIT License:\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "Assets/Colyseus/LICENSE.meta",
    "content": "fileFormatVersion: 2\nguid: 28fed75626a4d4144b26bef3670248f7\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Auth.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing GameDevWare.Serialization;\n\nnamespace Colyseus\n{\n\tpublic interface IAuthData\n\t{\n\t\tstring Token { get; }\n\t\tIndexedDictionary<string, object> RawUser { get; set; }\n\t\tType UserType { get; }\n\t}\n\n\t[Serializable]\n\tpublic class AuthData<T> : IAuthData\n\t{\n\t\tpublic string token;\n\t\tpublic T user;\n\n\t\tprivate IndexedDictionary<string, object> rawUser;\n\n\t\tpublic AuthData() { }\n\t\tpublic AuthData(string _token, IndexedDictionary<string, object> userData)\n\t\t{\n\t\t\ttoken = _token;\n\t\t\trawUser = userData;\n\n\t\t\tif (typeof(T) == typeof(IndexedDictionary<string, object>))\n\t\t\t{\n\t\t\t\tuser = (T)(object)rawUser;\n\t\t\t}\n\t\t\telse if (userData != null)\n\t\t\t{\n\t\t\t\tuser = ConvertType(userData);\n\t\t\t}\n\t\t}\n\n\t\tpublic string Token\n\t\t{\n\t\t\tget => token;\n\t\t}\n\n\t\tpublic IndexedDictionary<string, object> RawUser\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\t// TODO: refactor here...\n\t\t\t\tif (rawUser == null && typeof(T) == typeof(IndexedDictionary<string, object>))\n\t\t\t\t{\n\t\t\t\t\trawUser = (IndexedDictionary<string, object>)(object)user;\n\t\t\t\t}\n\t\t\t\treturn rawUser;\n\t\t\t}\n\t\t\tset => rawUser = value;\n\t\t}\n\n\t\tpublic Type UserType\n\t\t{\n\t\t\tget => typeof(T);\n\t\t}\n\n\t\tpublic static T ConvertType(IndexedDictionary<string, object> rawUser)\n\t\t{\n\t\t\tType targetType = typeof(T);\n\t\t\tT instance = (T)Activator.CreateInstance(targetType);\n\n\t\t\tfor (var i = 0; i < rawUser.Keys.Count; i++)\n\t\t\t{\n\t\t\t\tvar field = targetType.GetField(rawUser.Keys[i]);\n\t\t\t\tif (field != null)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tfield.SetValue(instance, Convert.ChangeType(rawUser.Values[i], field.FieldType));\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tColyseusContext.Logger.LogWarning(\"Colyseus.Auth: cannot convert \" + targetType.ToString() + \" property '\" + field.Name + \"' from \" + rawUser.Values[i].GetType() + \" to \" + field.FieldType + \" (\" + e.Message + \")\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn instance;\n\t\t}\n\t}\n\n\tpublic interface IAuthChangeHandler\n\t{\n\t\tType Type { get; }\n\t\tType UserType { get; set; }\n\t\tvoid Invoke(object authData);\n\t}\n\n\tpublic class AuthChangeHandler<T> : IAuthChangeHandler\n\t{\n\t\tprivate Type userType;\n\t\tpublic Action<T> Action;\n\t\tpublic void Invoke(object authData) { Action.Invoke((T)authData); }\n\t\tpublic Type Type { get => typeof(T); }\n\t\tpublic Type UserType { get => userType; set => userType = value; }\n\t}\n\n\t/// <summary>\n\t///     Colyseus.Auth\n\t/// </summary>\n\t/// <remarks>\n\t///     Colyseus Authentication Module Tools.\n\t///     See https://docs.colyseus.io/authentication/module/\n\t/// </remarks>\n\tpublic class Auth\n\t{\n\t\tpublic static string PATH = \"auth\";\n\t\tpublic static string TOKEN_CACHE_KEY = \"AuthToken\";\n\n\t\tprivate Client _client;\n\t\tprivate List<IAuthChangeHandler> OnChangeHandlers = new List<IAuthChangeHandler>();\n\t\tprivate bool initialized = false;\n\n\t\tpublic Auth(Client client)\n\t\t{\n\t\t\t_client = client;\n\t\t\tToken = ColyseusContext.TokenStorage.GetToken(TOKEN_CACHE_KEY);\n\t\t}\n\n\t\tpublic string Token\n\t\t{\n\t\t\tget => _client.Http.AuthToken;\n\t\t\tset => _client.Http.AuthToken = value;\n\t\t}\n\n\t\tpublic async Task<Action> OnChange<T>(Action<AuthData<T>> callback)\n\t\t{\n\t\t\tvar handler = new AuthChangeHandler<AuthData<T>>\n\t\t\t{\n\t\t\t\tAction = callback,\n\t\t\t\tUserType = typeof(T)\n\t\t\t};\n\n\t\t\tOnChangeHandlers.Add(handler);\n\n\t\t\tif (!initialized)\n\t\t\t{\n\t\t\t\tinitialized = true;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\temitChange(new AuthData<T> {\n\t\t\t\t\t\ttoken = Token,\n\t\t\t\t\t\tuser = await GetUserData<T>()\n\t\t\t\t\t});\n\t\t\t\t} catch (Exception e)\n\t\t\t\t{\n\t\t\t\t\tColyseusContext.Logger.LogWarning(e.ToString());\n\t\t\t\t\temitChange(new AuthData<object> { user = null, token = null });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn () => OnChangeHandlers.Remove(handler);\n\t\t}\n\n\t\tpublic async Task<T> GetUserData<T>()\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(Token))\n\t\t\t{\n\t\t\t\tthrow new Exception(\"missing Auth.Token\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn getAuthData<T>(await _client.Http.Request<AuthData<IndexedDictionary<string, object>>>(\"GET\", $\"{PATH}/userdata\")).user;\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task<AuthData<T>> RegisterWithEmailAndPassword<T>(string email, string password, Dictionary<string, object> options = null)\n\t\t{\n\t\t\tvar response = getAuthData<T>(await _client.Http.Request<AuthData<IndexedDictionary<string, object>>>(\"POST\", $\"{PATH}/register\", new Dictionary<string, object>\n\t\t\t{\n\t\t\t\t{ \"email\", email },\n\t\t\t\t{ \"password\", password },\n\t\t\t\t{ \"options\", options },\n\t\t\t}));\n\n\t\t\temitChange(response);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tpublic async Task<IAuthData> RegisterWithEmailAndPassword(string email, string password, Dictionary<string, object> options = null)\n\t\t{\n\t\t\treturn await RegisterWithEmailAndPassword<IndexedDictionary<string, object>>(email, password, options);\n\t\t}\n\n\t\tpublic async Task<AuthData<T>> SignInWithEmailAndPassword<T>(string email, string password)\n\t\t{\n\t\t\tvar response = getAuthData<T>(await _client.Http.Request<AuthData<IndexedDictionary<string, object>>>(\"POST\", $\"{PATH}/login\", new Dictionary<string, object>\n\t\t\t{\n\t\t\t\t{ \"email\", email },\n\t\t\t\t{ \"password\", password },\n\t\t\t}));\n\n\t\t\temitChange(response);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tpublic async Task<IAuthData> SignInWithEmailAndPassword(string email, string password)\n\t\t{\n\t\t\treturn await SignInWithEmailAndPassword<IndexedDictionary<string, object>>(email, password);\n\t\t}\n\n\t\tpublic async Task<AuthData<T>> SignInAnonymously<T>(Dictionary<string, object> options = null)\n\t\t{\n\t\t\tvar response = getAuthData<T>(await _client.Http.Request<AuthData<IndexedDictionary<string, object>>>(\"POST\", $\"{PATH}/anonymous\", options));\n\n\t\t\temitChange(response);\n\n\t\t\treturn response;\n\t\t}\n\n\t\tpublic async Task<IAuthData> SignInAnonymously(Dictionary<string, object> options = null)\n\t\t{\n\t\t\treturn await SignInAnonymously<IndexedDictionary<string, object>>(options);\n\t\t}\n\n\t\tpublic async Task<AuthData<T>> SignInWithProvider<T>(string providerName, Dictionary<string, object> settings = null)\n\t\t{\n\t\t\tawait Task.Run(() => {/* Satisfy the compiler async/await. This method is not implemented yet. */});\n\n\t\t\t//\n\t\t\t// Implementation reference: https://github.com/colyseus/colyseus.js/blob/1f2208d4ff49e858a737e4e7d1581148de196cce/src/Auth.ts#L112C26-L161\n\t\t\t//\n\t\t\tthrow new Exception(\"Not implemented. See implementation reference on JavaScript SDK\");\n\t\t}\n\t\tpublic async Task<IAuthData> SignInWithProvider(string providerName, Dictionary<string, object> settings = null)\n\t\t{\n\t\t\treturn await SignInWithProvider<IndexedDictionary<string, object>>(providerName, settings);\n\t\t}\n\n\t\tpublic async Task<string> SendResetPasswordEmail(string email, string password)\n\t\t{\n\t\t\treturn await _client.Http.Request(\"POST\", $\"{PATH}/login\", new Dictionary<string, object>\n\t\t\t{\n\t\t\t\t{ \"email\", email },\n\t\t\t\t{ \"password\", password },\n\t\t\t});\n\t\t}\n\n\t\tpublic void SignOut()\n\t\t{\n\t\t\temitChange(new AuthData<object> { token = null, user = null});\n\t\t}\n\n\t\tprivate void emitChange(IAuthData authData)\n\t\t{\n\t\t\tToken = authData.Token;\n\n\t\t\tif (!string.IsNullOrEmpty(Token))\n\t\t\t{\n\t\t\t\tColyseusContext.TokenStorage.SetToken(TOKEN_CACHE_KEY, authData.Token);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tColyseusContext.TokenStorage.DeleteToken(TOKEN_CACHE_KEY);\n\t\t\t}\n\n\t\t\tOnChangeHandlers.ForEach((handler) =>\n\t\t\t{\n\t\t\t\tif (authData.GetType() == handler.Type)\n\t\t\t\t{\n\t\t\t\t\thandler.Invoke(authData);\n\t\t\t\t}\n\t\t\t\telse if (authData.UserType == typeof(IndexedDictionary<string, object>))\n\t\t\t\t{\n\t\t\t\t\t// convert AuthData<handler.UserType>\n\t\t\t\t\tobject instance = Activator.CreateInstance(handler.Type, authData.Token, authData.RawUser);\n\t\t\t\t\thandler.Invoke(instance);\n\t\t\t\t}\n\t\t\t\telse if (authData.RawUser == null)\n\t\t\t\t{\n\t\t\t\t\tobject instance = Activator.CreateInstance(handler.Type, authData.Token, null);\n\t\t\t\t\thandler.Invoke(instance);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tColyseusContext.Logger.Log(\"Not triggering...\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tprivate AuthData<T> getAuthData<T>(AuthData<IndexedDictionary<string, object>> authData)\n\t\t{\n\t\t\tif (typeof(T) == typeof(IndexedDictionary<string, object>))\n\t\t\t{\n\t\t\t\treturn (AuthData<T>)(object)authData;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new AuthData<T>(authData.token, authData.RawUser);\n\t\t\t}\n\t\t}\n\n\t}\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Auth.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c500d710fb1854e15ac69bebeab976b6"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Client.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\n// ReSharper disable InconsistentNaming\n\nnamespace Colyseus\n{\n\t/// <summary>\n\t///     Options for latency measurement.\n\t/// </summary>\n\tpublic class LatencyOptions\n\t{\n\t\t/// <summary>\n\t\t///     \"ws\" for WebSocket, \"h3\" for WebTransport (default: \"ws\")\n\t\t/// </summary>\n\t\tpublic string Protocol { get; set; } = \"ws\";\n\n\t\t/// <summary>\n\t\t///     Number of pings to send (default: 1). Returns the average latency when > 1.\n\t\t/// </summary>\n\t\tpublic int PingCount { get; set; } = 1;\n\t}\n\n\t/// <summary>\n\t///     Colyseus.Client\n\t/// </summary>\n\t/// <remarks>\n\t///     Provides integration between Colyseus Game Server through WebSocket protocol (\n\t///     <see href=\"http://tools.ietf.org/html/rfc6455\">RFC 6455</see>).\n\t/// </remarks>\n\tpublic class Client\n\t{\n\t\t/// <summary>\n\t\t///     Authentication tools, see: https://docs.colyseus.io/auth/\n\t\t/// </summary>\n\t\tpublic Auth Auth;\n\n\t\t/// <summary>\n\t\t///     Reference to the client's <see cref=\"UriBuilder\" />\n\t\t/// </summary>\n\t\tprivate UriBuilder Endpoint;\n\n\t\t/// <summary>\n\t\t/// Object to perform <see cref=\"UnityEngine.Networking.UnityWebRequest\"/>s to the server.\n\t\t/// </summary>\n\t\tpublic HTTP Http;\n\n\t\t/// <summary>\n\t\t///     Initializes a new instance of the <see cref=\"Client\" /> class with\n\t\t///     the specified Colyseus Game Server endpoint.\n\t\t/// </summary>\n\t\t/// <param name=\"endpoint\">\n\t\t///     A <see cref=\"string\" /> that represents the WebSocket URL to connect.\n\t\t/// </param>\n\t\tpublic Client(string endpoint)\n\t\t{\n\t\t\tEndpoint = new UriBuilder(endpoint);\n\n\t\t\t// Create Settings object to pass to the ColyseusRequest object\n\t\t\tSettings settings = Settings.Create();\n\t\t\tsettings.colyseusServerAddress = $\"{Endpoint.Host}{Endpoint.Path}\";\n\t\t\tsettings.colyseusServerPort = Endpoint.Port.ToString();\n\t\t\tsettings.useSecureProtocol = string.Equals(Endpoint.Scheme, \"wss\") || string.Equals(Endpoint.Scheme, \"https\");\n\n\t\t\tSettings = settings;\n\t\t\tAuth = new Auth(this);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"Client\"/> class with\n\t\t/// the specified Colyseus Settings object.\n\t\t/// </summary>\n\t\t/// <param name=\"settings\">The settings you wish to use</param>\n\t\t/// <param name=\"useWebSocketEndpoint\">Determines whether the connection endpoint should use either web socket or http protocols.</param>\n\t\tpublic Client(Settings settings)\n\t\t{\n\t\t\tSettings = settings;\n\t\t\tAuth = new Auth(this);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The getter for the <see cref=\"Settings\"/> currently assigned to this client object\n\t\t/// </summary>\n\t\tprivate Settings _colyseusSettings;\n\t\tpublic Settings Settings\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\treturn _colyseusSettings;\n\t\t\t}\n\n\t\t\tset\n\t\t\t{\n\t\t\t\t_colyseusSettings = value;\n\n\t\t\t\tEndpoint = new UriBuilder(_colyseusSettings.WebSocketEndpoint);\n\n\t\t\t\t// Instantiate our ColyseusRequest object with the settings object\n\t\t\t\tHttp = new HTTP(_colyseusSettings);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Join or Create a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomName\">Room identifier</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon creation/joining</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we create/join the room</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we want to join or create</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<T>> JoinOrCreate<T>(string roomName, Dictionary<string, object> options = null, Dictionary<string, string> headers = null)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<T>(\"joinOrCreate\", roomName, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Create a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomName\">Room identifier</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon creation</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we create the room</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we want to create</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<T>> Create<T>(string roomName, Dictionary<string, object> options = null, Dictionary<string, string> headers = null)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<T>(\"create\", roomName, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Join a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomName\">Room identifier</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon joining</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we join the room</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we want to join</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<T>> Join<T>(string roomName, Dictionary<string, object> options = null, Dictionary<string, string> headers = null)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<T>(\"join\", roomName, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Join a <see cref=\"Room{T}\" /> by ID\n\t\t/// </summary>\n\t\t/// <param name=\"roomId\">ID of the room</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon joining</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we join the room</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we want to join</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<T>> JoinById<T>(string roomId, Dictionary<string, object> options = null, Dictionary<string, string> headers = null)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<T>(\"joinById\", roomId, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Reconnect to a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"reconnectionToken\">Previously connected ReconnectionToken</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we reconnect to the room</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we want to reconnect with</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<T>> Reconnect<T>(ReconnectionToken reconnectionToken, Dictionary<string, string> headers = null)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\tDictionary<string, object> options = new Dictionary<string, object>();\n\t\t\toptions.Add(\"reconnectionToken\", reconnectionToken.Token);\n\t\t\treturn await CreateMatchMakeRequest<T>(\"reconnect\", reconnectionToken.RoomId, options, headers);\n\t\t}\n\n\t\t//\n\t\t// FossilDelta/None serializer versions for joining the state\n\t\t//\n\t\t/// <summary>\n\t\t///     Join or Create a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomName\">Room identifier</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon creation/joining</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we create/join the room</param>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<NoState>> JoinOrCreate(string roomName, Dictionary<string, object> options = null, Dictionary<string, string> headers = null)\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<NoState>(\"joinOrCreate\", roomName, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Create a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomName\">Room identifier</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon creation</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we create the room</param>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<NoState>> Create(string roomName, Dictionary<string, object> options = null,\n\t\t\tDictionary<string, string> headers = null)\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<NoState>(\"create\", roomName, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Join a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomName\">Room identifier</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon joining</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we join the room</param>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<NoState>> Join(string roomName, Dictionary<string, object> options = null,\n\t\t\tDictionary<string, string> headers = null)\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<NoState>(\"join\", roomName, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Join a <see cref=\"Room{T}\" /> by ID\n\t\t/// </summary>\n\t\t/// <param name=\"roomId\">ID of the room</param>\n\t\t/// <param name=\"options\">Dictionary of options to pass to the room upon joining</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we join the room</param>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<NoState>> JoinById(string roomId, Dictionary<string, object> options = null,\n\t\t\tDictionary<string, string> headers = null)\n\t\t{\n\t\t\treturn await CreateMatchMakeRequest<NoState>(\"joinById\", roomId, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Reconnect to a <see cref=\"Room{T}\" />\n\t\t/// </summary>\n\t\t/// <param name=\"roomId\">ID of the room</param>\n\t\t/// <param name=\"sessionId\">Previously connected sessionId</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server when we reconnect to the room</param>\n\t\t/// <returns><see cref=\"Room{T}\" /> via async task</returns>\n\t\tpublic async Task<Room<NoState>> Reconnect(string roomId, string sessionId,\n\t\t\tDictionary<string, string> headers = null)\n\t\t{\n\t\t\tDictionary<string, object> options = new Dictionary<string, object>();\n\t\t\toptions.Add(\"sessionId\", sessionId);\n\t\t\treturn await CreateMatchMakeRequest<NoState>(\"joinById\", roomId, options, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Consume the seat reservation\n\t\t/// </summary>\n\t\t/// <param name=\"response\">The response from the matchmaking attempt</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server</param>\n\t\t/// <param name=\"previousRoom\">Previous Room{T} instance to re-establish the server connection: Please do not use this devMode param for general purposes</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we're consuming the seat from</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> in which we now have a seat via async task</returns>\n\t\tpublic async Task<Room<T>> ConsumeSeatReservation<T>(SeatReservation response, Dictionary<string, string> headers = null)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\tRoom<T> room = new Room<T>(response.name)\n\t\t\t{\n\t\t\t\tRoomId = response.roomId,\n\t\t\t\tSessionId = response.sessionId\n\t\t\t};\n\n\t\t\tDictionary<string, object> queryString = new Dictionary<string, object>\n\t\t\t{\n\t\t\t\t{ \"sessionId\", room.SessionId }\n\t\t\t};\n\n\t\t\t// forward reconnection token\n\t\t\tif (response.reconnectionToken != null)\n\t\t\t{\n\t\t\t\tqueryString.Add(\"reconnectionToken\", response.reconnectionToken);\n\t\t\t}\n\n\t\t\troom.SetConnection(CreateConnection(response, queryString, headers));\n\n\t\t\tTaskCompletionSource<Room<T>> tcs = new TaskCompletionSource<Room<T>>();\n\n\t\t\tvoid OnError(int code, string message)\n\t\t\t{\n\t\t\t\troom.OnError -= OnError;\n\t\t\t\ttcs.SetException(new MatchMakeException(code, message));\n\t\t\t}\n\n\t\t\tvoid OnJoin()\n\t\t\t{\n\t\t\t\troom.OnError -= OnError;\n\t\t\t\ttcs.TrySetResult(room);\n\t\t\t}\n\n\t\t\troom.OnError += OnError;\n\t\t\troom.OnJoin += OnJoin;\n\n\t\t\t_ = room.Connect();\n\n\t\t\treturn await tcs.Task;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Create a match making request\n\t\t/// </summary>\n\t\t/// <param name=\"method\">The type of request we're making (join, create, etc)</param>\n\t\t/// <param name=\"roomName\">Room identifierroom we're trying to match</param>\n\t\t/// <param name=\"options\">Dictionary of options to use in the match making process</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass to the server</param>\n\t\t/// <typeparam name=\"T\">Type of <see cref=\"Room{T}\" /> we want to match with</typeparam>\n\t\t/// <returns><see cref=\"Room{T}\" /> we have matched with via async task</returns>\n\t\t/// <exception cref=\"Exception\">Thrown if there is a network related error</exception>\n\t\t/// <exception cref=\"MatchMakeException\">Thrown if there is an error in the match making process on the server side</exception>\n\t\tprotected async Task<Room<T>> CreateMatchMakeRequest<T>(string method, string roomName, Dictionary<string, object> options, Dictionary<string, string> headers)\n\t\t\twhere T : Schema.Schema\n\t\t{\n\t\t\tif (options == null)\n\t\t\t{\n\t\t\t\toptions = new Dictionary<string, object>();\n\t\t\t}\n\n\t\t\tif (headers == null)\n\t\t\t{\n\t\t\t\theaders = new Dictionary<string, string>();\n\t\t\t}\n\n\t\t\tvar response = await Http.Post<SeatReservation>($\"matchmake/{method}/{roomName}\", options, headers);\n\n\t\t\tif (response == null)\n\t\t\t{\n\t\t\t\tthrow new Exception($\"Error with request: {response}\");\n\t\t\t}\n\t\t\t// forward reconnection token on reconnect\n\t\t\tif (method == \"reconnect\")\n\t\t\t{\n\t\t\t\tresponse.reconnectionToken = (string)options[\"reconnectionToken\"];\n\t\t\t}\n\n\t\t\treturn await ConsumeSeatReservation<T>(response, headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Create a connection with a room\n\t\t/// </summary>\n\t\t/// <param name=\"path\">Additional info used as the <see cref=\"UriBuilder.Path\" /></param>\n\t\t/// <param name=\"options\">Dictionary of options to use when connecting</param>\n\t\t/// <param name=\"headers\">Dictionary of headers to pass when connecting</param>\n\t\t/// <returns></returns>\n\t\tprotected Connection CreateConnection(\n\t\t\tSeatReservation room,\n\t\t\tDictionary<string, object> options = null,\n\t\t\tDictionary<string, string> headers = null\n\t\t)\n\t\t{\n\t\t\tif (room.protocol != null && room.protocol == \"h3\") {\n\t\t\t\t// TODO: support h3 protocol (WebTransport)\n\t\t\t\tthrow new Exception(\"WebTransport protocol is not supported yet. Please use WebSocket protocol instead.\");\n\t\t\t}\n\n\t\t\tif (options == null)\n\t\t\t{\n\t\t\t\toptions = new Dictionary<string, object>();\n\t\t\t}\n\n\t\t\t// Add authentication token to query string\n\t\t\tif (!string.IsNullOrEmpty(Http.AuthToken))\n\t\t\t{\n\t\t\t\toptions.Add(\"_authToken\", Http.AuthToken);\n\t\t\t}\n\n\t\t\tList<string> list = new List<string>();\n\t\t\tforeach (KeyValuePair<string, object> item in options)\n\t\t\t{\n\t\t\t\tlist.Add(item.Key + \"=\" + (item.Value != null ? Convert.ToString(item.Value) : \"null\"));\n\t\t\t}\n\n\t\t\t// Try to connect directly to custom publicAddress, if present.\n\t\t\tvar endpoint = (room.publicAddress != null && room.publicAddress.Length > 0)\n\t\t\t\t? new Uri($\"{Endpoint.Scheme}://{room.publicAddress}\")\n\t\t\t\t: Endpoint.Uri;\n\n\t\t\tvar basePath = endpoint.AbsolutePath;\n\n\t\t\t// make sure to end path with backslash\n\t\t\tif (basePath.Length > 0 && !basePath.EndsWith(\"/\"))\n\t\t\t{\n\t\t\t\tbasePath += \"/\";\n\t\t\t}\n\n\t\t\tUriBuilder uriBuilder = new UriBuilder(endpoint)\n\t\t\t{\n\t\t\t\tPath = $\"{basePath}{room.processId}/{room.roomId}\",\n\t\t\t\tQuery = string.Join(\"&\", list.ToArray())\n\t\t\t};\n\n\t\t\treturn new Connection(uriBuilder.ToString(), headers);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Select the endpoint with the lowest latency.\n\t\t/// </summary>\n\t\t/// <param name=\"endpoints\">Array of endpoints to select from.</param>\n\t\t/// <param name=\"latencyOptions\">Latency measurement options (protocol, pingCount).</param>\n\t\t/// <returns>The client with the lowest latency.</returns>\n\t\tpublic static async Task<Client> SelectByLatency(string[] endpoints, LatencyOptions latencyOptions = null)\n\t\t{\n\t\t\tif (latencyOptions == null)\n\t\t\t{\n\t\t\t\tlatencyOptions = new LatencyOptions();\n\t\t\t}\n\n\t\t\tvar clients = new Client[endpoints.Length];\n\t\t\tfor (int i = 0; i < endpoints.Length; i++)\n\t\t\t{\n\t\t\t\tclients[i] = new Client(endpoints[i]);\n\t\t\t}\n\n\t\t\tvar latencyTasks = new Task<(int index, double latency, bool success)>[clients.Length];\n\t\t\tfor (int i = 0; i < clients.Length; i++)\n\t\t\t{\n\t\t\t\tint index = i;\n\t\t\t\tlatencyTasks[i] = MeasureClientLatency(clients[index], index, latencyOptions);\n\t\t\t}\n\n\t\t\tvar results = await Task.WhenAll(latencyTasks);\n\n\t\t\tint bestIndex = -1;\n\t\t\tdouble bestLatency = double.MaxValue;\n\n\t\t\tfor (int i = 0; i < results.Length; i++)\n\t\t\t{\n\t\t\t\tif (results[i].success && results[i].latency < bestLatency)\n\t\t\t\t{\n\t\t\t\t\tbestLatency = results[i].latency;\n\t\t\t\t\tbestIndex = results[i].index;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bestIndex == -1)\n\t\t\t{\n\t\t\t\tthrow new Exception(\"All endpoints failed to respond\");\n\t\t\t}\n\n\t\t\treturn clients[bestIndex];\n\t\t}\n\n\t\tprivate static async Task<(int index, double latency, bool success)> MeasureClientLatency(Client client, int index, LatencyOptions options)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar latency = await client.GetLatency(options);\n\t\t\t\tvar settings = client.Settings;\n\t\t\t\tColyseusContext.Logger.Log($\"Endpoint Latency: {latency}ms - {settings.colyseusServerAddress}:{settings.colyseusServerPort}\");\n\t\t\t\treturn (index, latency, success: true);\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\treturn (index, latency: double.MaxValue, success: false);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Create a new connection with the server, and measure the latency.\n\t\t/// </summary>\n\t\t/// <param name=\"options\">Latency measurement options (protocol, pingCount).</param>\n\t\t/// <returns>The average latency in milliseconds.</returns>\n\t\tpublic Task<double> GetLatency(LatencyOptions options = null)\n\t\t{\n\t\t\tif (options == null)\n\t\t\t{\n\t\t\t\toptions = new LatencyOptions();\n\t\t\t}\n\n\t\t\tvar protocol = options.Protocol ?? \"ws\";\n\t\t\tvar pingCount = options.PingCount > 0 ? options.PingCount : 1;\n\n\t\t\tif (protocol == \"h3\")\n\t\t\t{\n\t\t\t\tthrow new Exception(\"WebTransport protocol is not supported yet. Please use WebSocket protocol instead.\");\n\t\t\t}\n\n\t\t\tvar tcs = new TaskCompletionSource<double>();\n\t\t\tvar latencies = new List<double>();\n\t\t\tlong pingStart = 0;\n\n\t\t\tvar conn = new Connection(Endpoint.ToString(), null);\n\n\t\t\tvoid OnOpen()\n\t\t\t{\n\t\t\t\tpingStart = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n\t\t\t\t_ = conn.Send(new byte[] { Protocol.PING });\n\t\t\t}\n\n\t\t\tvoid OnMessage(byte[] data)\n\t\t\t{\n\t\t\t\tlatencies.Add(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - pingStart);\n\n\t\t\t\tif (latencies.Count < pingCount)\n\t\t\t\t{\n\t\t\t\t\t// Send another ping\n\t\t\t\t\tpingStart = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n\t\t\t\t\t_ = conn.Send(new byte[] { Protocol.PING });\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Done, calculate average and close\n\t\t\t\t\tconn.OnOpen -= OnOpen;\n\t\t\t\t\tconn.OnMessage -= OnMessage;\n\t\t\t\t\tconn.OnError -= OnError;\n\n\t\t\t\t\t_ = conn.Close();\n\n\t\t\t\t\tdouble sum = 0;\n\t\t\t\t\tfor (int i = 0; i < latencies.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tsum += latencies[i];\n\t\t\t\t\t}\n\t\t\t\t\ttcs.TrySetResult(sum / latencies.Count);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid OnError(string errorMsg)\n\t\t\t{\n\t\t\t\tconn.OnOpen -= OnOpen;\n\t\t\t\tconn.OnMessage -= OnMessage;\n\t\t\t\tconn.OnError -= OnError;\n\n\t\t\t\ttcs.TrySetException(new MatchMakeException((int)CloseCode.ABNORMAL_CLOSURE, $\"Failed to get latency: {errorMsg}\"));\n\t\t\t}\n\n\t\t\tconn.OnOpen += OnOpen;\n\t\t\tconn.OnMessage += OnMessage;\n\t\t\tconn.OnError += OnError;\n\n\t\t\t_ = conn.Connect();\n\n\t\t\treturn tcs.Task;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Client.cs.meta",
    "content": "fileFormatVersion: 2\nguid: b31ab8167fc564dee91f45b0dd6d57ff"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Connection.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n// ReSharper disable InconsistentNaming\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     WebSocket connection representation with some custom functionality\n    /// </summary>\n    public class Connection\n    {\n        public event WebSocketOpenEventHandler OnOpen;\n        public event WebSocketMessageEventHandler OnMessage;\n        public event WebSocketErrorEventHandler OnError;\n        public event WebSocketCloseEventHandler OnClose;\n\n        /// <summary>\n        ///     Is the connection currently open\n        /// </summary>\n        public bool IsOpen;\n\n        private WebSocketTransport _transport;\n        private string _url;\n        private Dictionary<string, string> _headers;\n\n        public Connection(string url, Dictionary<string, string> headers)\n        {\n            _url = url;\n            _headers = headers;\n        }\n\n        public async Task Connect()\n        {\n            _transport = new WebSocketTransport();\n\n            _transport.OnOpen += () => { IsOpen = true; OnOpen?.Invoke(); };\n            _transport.OnMessage += (data) => OnMessage?.Invoke(data);\n            _transport.OnError += (msg) => OnError?.Invoke(msg);\n            _transport.OnClose += (code) => { IsOpen = false; OnClose?.Invoke(code); };\n\n            await _transport.Connect(_url, _headers);\n        }\n\n        public Task Send(byte[] data)\n        {\n            return _transport.Send(data);\n        }\n\n        public Task Close()\n        {\n            return _transport.Close();\n        }\n\n\t\tpublic void Drop()\n\t\t{\n\t\t\tCancelConnection();\n\t\t}\n\n        public void CancelConnection()\n        {\n            _transport?.CancelConnection();\n        }\n\n#if !UNITY_WEBGL || UNITY_EDITOR\n        /// <summary>\n        /// Dispatch queued WebSocket callbacks manually from a custom game loop.\n        /// This is only needed when no SynchronizationContext or external dispatcher is available.\n        /// </summary>\n        public void DispatchMessageQueue()\n        {\n            _transport?.DispatchMessageQueue();\n        }\n#endif\n\n        /// <summary>\n        ///     Reconnect to the same endpoint with a new reconnection token\n        /// </summary>\n        /// <param name=\"reconnectionToken\">The token to use for reconnection</param>\n        public async Task Reconnect(string reconnectionToken)\n        {\n            var uri = new Uri(_url);\n            var queryParams = new List<string>();\n\n            // Preserve existing query parameters\n            if (!string.IsNullOrEmpty(uri.Query))\n            {\n                var existingQuery = uri.Query.TrimStart('?');\n                if (!string.IsNullOrEmpty(existingQuery))\n                {\n                    foreach (var param in existingQuery.Split('&'))\n                    {\n                        var key = param.Split('=')[0];\n                        // Skip params we're going to override\n                        if (key != \"reconnectionToken\" && key != \"skipHandshake\")\n                        {\n                            queryParams.Add(param);\n                        }\n                    }\n                }\n            }\n\n            queryParams.Add(\"reconnectionToken=\" + Uri.EscapeDataString(reconnectionToken));\n            queryParams.Add(\"skipHandshake=1\");\n\n            var uriBuilder = new UriBuilder(uri) { Query = string.Join(\"&\", queryParams) };\n            _url = uriBuilder.ToString();\n\n            ColyseusContext.Logger.Log($\"Reconnecting to {_url}\");\n            await Connect();\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Connection.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c7b2c7c29325c4b2f81ddd0c68c1f995"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/HTTP.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing System.IO;\nusing GameDevWare.Serialization;\n\nnamespace Colyseus\n{\n    [Serializable]\n    public class ErrorResponse\n\t{\n        public string error;\n\t}\n\n    /// <summary>\n    /// Class for building out server requests\n    /// </summary>\n    public class HTTP\n    {\n        public string AuthToken;\n\n        private Settings _settings;\n\n        public HTTP(Settings settings)\n        {\n            _settings = settings;\n        }\n\n        public async Task<string> Get(string uriPath, Dictionary<string, string> headers = null)\n        {\n            return await Request(\"GET\", uriPath, null, headers);\n        }\n\n        public async Task<T> Get<T>(string uriPath, Dictionary<string, string> headers = null)\n        {\n            return await Request<T>(\"GET\", uriPath, null, headers);\n        }\n\n        public async Task<string> Post(string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return await Request(\"POST\", uriPath, jsonBody, headers);\n        }\n\n        public async Task<T> Post<T>(string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return await Request<T>(\"POST\", uriPath, jsonBody, headers);\n        }\n\n        public async Task<string> Delete(string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return await Request(\"DELETE\", uriPath, jsonBody, headers);\n        }\n\n        public async Task<T> Delete<T>(string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return await Request<T>(\"DELETE\", uriPath, jsonBody, headers);\n        }\n\n        public async Task<string> Put(string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return await Request(\"PUT\", uriPath, jsonBody, headers);\n        }\n\n        public async Task<T> Put<T>(string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return await Request<T>(\"PUT\", uriPath, jsonBody, headers);\n        }\n\n        public async Task<T> Request<T>(string uriMethod, string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            return Json.Deserialize<T>(await Request(uriMethod, uriPath, jsonBody, headers));\n        }\n\n        public async Task<string> Request(string uriMethod, string uriPath, Dictionary<string, object> jsonBody = null, Dictionary<string, string> headers = null)\n        {\n            byte[] body = null;\n            if (jsonBody != null)\n            {\n                MemoryStream jsonBodyStream = new MemoryStream();\n                Json.Serialize(jsonBody, jsonBodyStream);\n                body = jsonBodyStream.ToArray();\n            }\n\n            var allHeaders = new Dictionary<string, string>();\n\n            foreach (KeyValuePair<string, string> pair in _settings.Headers)\n            {\n                allHeaders[pair.Key] = pair.Value;\n            }\n\n            if (!string.IsNullOrEmpty(AuthToken))\n            {\n                allHeaders[\"Authorization\"] = \"Bearer \" + AuthToken;\n            }\n\n            if (headers != null)\n            {\n                foreach (KeyValuePair<string, string> header in headers)\n                {\n                    allHeaders[header.Key] = header.Value;\n                }\n            }\n\n            return await ColyseusContext.HttpClient.Request(uriMethod, GetRequestURL(uriPath), body, allHeaders);\n        }\n\n        public string GetRequestURL(string pathWithQueryString)\n        {\n            var splittedPath = pathWithQueryString.Split('?');\n            var path = splittedPath[0];\n            var query = (splittedPath.Length > 1) ? splittedPath[1] : \"\";\n\n            string forwardSlash = \"\";\n            if (!_settings.WebRequestEndpoint.EndsWith(\"/\"))\n            {\n                forwardSlash = \"/\";\n            }\n\n            // WebRequestEndpoint will include any path that is included with the server address field of the server settings object so we need to add the request specific path to the WebRequestEndpoint value\n            UriBuilder uriBuilder = new UriBuilder($\"{_settings.WebRequestEndpoint}{forwardSlash}{path}\");\n\n            uriBuilder.Port = _settings.GetPort();\n\n            if (!string.IsNullOrEmpty(query))\n\t\t\t{\n                uriBuilder.Query = query;\n            }\n\n            return uriBuilder.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/HTTP.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ee3501581e55f44c8909b6ec76944724\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Manager.cs",
    "content": "using System.Collections.Generic;\nusing UnityEngine;\n// ReSharper disable InconsistentNaming\n\nnamespace Colyseus\n{\n    /// <summary>\n    /// Base manager class\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    public class Manager<T> : MonoBehaviour\n        where T: Component\n    {\n        /// <summary>\n        /// Reference to the Colyseus settings object.\n        /// </summary>\n        [SerializeField]\n        protected Settings _colyseusSettings;\n\n        // Getters\n        //==========================\n        /// <summary>\n        /// The singleton instance of the Colyseus Manager.\n        /// </summary>\n        public static T Instance { get; private set; }\n\n        /// <summary>\n        /// Returns the Colyseus server address as defined\n        /// in the <see cref=\"Settings\"/> object\n        /// </summary>\n        public string ColyseusServerAddress\n        {\n            get { return _colyseusSettings.colyseusServerAddress; }\n        }\n\n        /// <summary>\n        /// Returns the Colyseus server port as defined\n        /// in the <see cref=\"Settings\"/> object\n        /// </summary>\n        public string ColyseusServerPort\n        {\n            get { return _colyseusSettings.colyseusServerPort; }\n        }\n\n        /// <summary>\n        /// Returned if the desired protocol security as defined\n        /// in the <see cref=\"Settings\"/> object\n        /// </summary>\n        public bool ColyseusUseSecure\n        {\n            get { return _colyseusSettings.useSecureProtocol; }\n        }\n        //==========================\n\n        /// <summary>\n        /// The primary Client object responsible for making connections to the server.\n        /// </summary>\n        protected Client client;\n\n        /// <summary>\n        /// <see cref=\"MonoBehaviour\"/> callback when the manager object has been destroyed.\n        /// </summary>\n        protected virtual void OnDestroy()\n        {\n        }\n\n        /// <summary>\n        /// <see cref=\"MonoBehaviour\"/> callback when the script instance is being loaded.\n        /// </summary>\n        protected virtual void Awake()\n        {\n            InitializeInstance();\n        }\n\n        /// <summary>\n        /// Initializes the Colyseus manager singleton.\n        /// </summary>\n        private void InitializeInstance()\n        {\n            if (Instance != null)\n            {\n                Destroy(gameObject);\n                return;\n            }\n\n            Instance = this as T;\n        }\n\n        /// <summary>\n        /// <see cref=\"MonoBehaviour\"/> callback when a script is enabled just before any of the Update methods are called the first time.\n        /// </summary>\n        protected virtual void Start()\n        {\n        }\n\n        /// <summary>\n        /// Frame-rate independent message for physics calculations.\n        /// </summary>\n        protected virtual void FixedUpdate()\n        {\n        }\n\n        /// <summary>\n        /// Override the current <see cref=\"Settings\"/>\n        /// </summary>\n        /// <param name=\"newSettings\">The new settings to use</param>\n        public virtual void OverrideSettings(Settings newSettings)\n        {\n            _colyseusSettings = newSettings;\n\n            if (client != null)\n\t\t\t{\n                client.Settings = newSettings;\n            }\n        }\n\n        /// <summary>\n        /// Get a copy of the manager's settings configuration\n        /// </summary>\n        /// <returns></returns>\n        public virtual Settings CloneSettings()\n        {\n            return Settings.Clone(_colyseusSettings);\n        }\n\n        /// <summary>\n        /// Creates a new <see cref=\"Client\"/> object, with the given endpoint, and returns it\n        /// </summary>\n        /// <param name=\"endpoint\">URL to the Colyseus server</param>\n        /// <returns></returns>\n        public Client CreateClient(string endpoint)\n        {\n            client = new Client(endpoint);\n            return client;\n        }\n\n        /// <summary>\n        /// /// Create a new <see cref=\"Client\"/> along with any other client initialization you may need to perform\n        /// /// </summary>\n        public virtual void InitializeClient()\n        {\n            CreateClient(_colyseusSettings.WebSocketEndpoint);\n        }\n\n        /// <summary>\n        /// <see cref=\"MonoBehaviour\"/> callback that gets called just before app exit.\n        /// </summary>\n        protected virtual void OnApplicationQuit()\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Manager.cs.meta",
    "content": "fileFormatVersion: 2\nguid: dfd046c2a7f284b40abeb2e9c6030c2a"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/ColyseusContext.cs",
    "content": "using System;\n\nnamespace Colyseus\n{\n    public static class ColyseusContext\n    {\n        public static ILogger Logger { get; set; }\n        public static IHttpClient HttpClient { get; set; }\n        public static ITokenStorage TokenStorage { get; set; }\n\n        /// <summary>\n        /// When set, WebSocketTransport registers websockets here for external\n        /// dispatching (e.g. MonoGame or a custom engine loop) instead of relying\n        /// on SynchronizationContext dispatch or the shared fallback dispatcher.\n        /// </summary>\n        public static Action<NativeWebSocket.WebSocket> RegisterWebSocketForDispatch { get; set; }\n        public static Action<NativeWebSocket.WebSocket> UnregisterWebSocketForDispatch { get; set; }\n\n        static ColyseusContext()\n        {\n            SetDefaults();\n        }\n\n        public static void SetDefaults()\n        {\n            Logger = new ConsoleLogger();\n            HttpClient = new DefaultHttpClient();\n            TokenStorage = new InMemoryTokenStorage();\n            RegisterWebSocketForDispatch = null;\n            UnregisterWebSocketForDispatch = null;\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/ColyseusContext.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e9d11516d4fd945f6bc6f9c38f59484f"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults/ConsoleLogger.cs",
    "content": "using System;\n\nnamespace Colyseus\n{\n    public class ConsoleLogger : ILogger\n    {\n        public void Log(string message)\n        {\n            Console.WriteLine(message);\n        }\n\n        public void LogWarning(string message)\n        {\n            Console.WriteLine(\"[WARNING] \" + message);\n        }\n\n        public void LogError(string message)\n        {\n            Console.Error.WriteLine(\"[ERROR] \" + message);\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults/ConsoleLogger.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c61bec0c4a8f5466ead316cf8b48a7c3"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults/DefaultHttpClient.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nnamespace Colyseus\n{\n    public class DefaultHttpClient : IHttpClient\n    {\n        private static readonly HttpClient _client = new HttpClient();\n\n        public async Task<string> Request(string method, string url, byte[] body, Dictionary<string, string> headers)\n        {\n            var request = new HttpRequestMessage(new HttpMethod(method), url);\n\n            if (body != null)\n            {\n                request.Content = new ByteArrayContent(body);\n                request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(\"application/json\");\n            }\n\n            if (headers != null)\n            {\n                foreach (var header in headers)\n                {\n                    request.Headers.TryAddWithoutValidation(header.Key, header.Value);\n                }\n            }\n\n            var response = await _client.SendAsync(request);\n            var responseBody = await response.Content.ReadAsStringAsync();\n\n            if (!response.IsSuccessStatusCode)\n            {\n                throw new HttpException((int)response.StatusCode, responseBody);\n            }\n\n            return responseBody;\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults/DefaultHttpClient.cs.meta",
    "content": "fileFormatVersion: 2\nguid: b76ed9cf151944e27a2b3dd129f71ec1"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults/InMemoryTokenStorage.cs",
    "content": "using System.Collections.Generic;\n\nnamespace Colyseus\n{\n    public class InMemoryTokenStorage : ITokenStorage\n    {\n        private Dictionary<string, string> _tokens = new Dictionary<string, string>();\n\n        public string GetToken(string key)\n        {\n            _tokens.TryGetValue(key, out var value);\n            return value ?? string.Empty;\n        }\n\n        public void SetToken(string key, string value)\n        {\n            _tokens[key] = value;\n        }\n\n        public void DeleteToken(string key)\n        {\n            _tokens.Remove(key);\n        }\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults/InMemoryTokenStorage.cs.meta",
    "content": "fileFormatVersion: 2\nguid: f08fd06971bb7429493182bdbe6bc586"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Defaults.meta",
    "content": "fileFormatVersion: 2\nguid: a936aa0bb60cb45839f98f94e6b99ff3\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/IHttpClient.cs",
    "content": "using System.Collections.Generic;\nusing System.Threading.Tasks;\n\nnamespace Colyseus\n{\n    public interface IHttpClient\n    {\n        Task<string> Request(string method, string url, byte[] body, Dictionary<string, string> headers);\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/IHttpClient.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d0b5fc7c6915d4fbb8d3912865fa3a39"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/ILogger.cs",
    "content": "namespace Colyseus\n{\n    public interface ILogger\n    {\n        void Log(string message);\n        void LogWarning(string message);\n        void LogError(string message);\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/ILogger.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 7a651e0ae0860483aa3bdd31fb0c1ff0"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/ITokenStorage.cs",
    "content": "namespace Colyseus\n{\n    public interface ITokenStorage\n    {\n        string GetToken(string key);\n        void SetToken(string key, string value);\n        void DeleteToken(string key);\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/ITokenStorage.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a28d0b00b73cb4b5e88d58109c69b4bc"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/IWebSocket.cs",
    "content": "namespace Colyseus\n{\n    public delegate void WebSocketOpenEventHandler();\n    public delegate void WebSocketMessageEventHandler(byte[] data);\n    public delegate void WebSocketErrorEventHandler(string errorMsg);\n    public delegate void WebSocketCloseEventHandler(int closeCode);\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/IWebSocket.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3fe20329183ae4a0eb091fee0b8a61bc"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/PreserveAttribute.cs",
    "content": "using System;\n\nnamespace Colyseus\n{\n    /// <summary>\n    /// Custom Preserve attribute that works on all platforms.\n    /// Unity's IL2CPP linker recognizes any attribute named \"Preserve\" regardless of namespace.\n    /// </summary>\n    [AttributeUsage(AttributeTargets.All)]\n    public sealed class PreserveAttribute : Attribute { }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/PreserveAttribute.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3123978311a4e4dd68b79ae85a198a18"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityHttpClient.cs",
    "content": "#if UNITY_5_3_OR_NEWER\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing UnityEngine;\nusing UnityEngine.Networking;\nusing GameDevWare.Serialization;\n\nnamespace Colyseus\n{\n    public class UnityHttpClient : IHttpClient\n    {\n        public async Task<string> Request(string method, string url, byte[] body, Dictionary<string, string> headers)\n        {\n            using (UnityWebRequest req = new UnityWebRequest())\n            {\n                req.method = method;\n                req.url = url;\n\n                if (body != null)\n                {\n                    req.uploadHandler = new UploadHandlerRaw(body)\n                    {\n                        contentType = \"application/json\"\n                    };\n                }\n\n                if (headers != null)\n                {\n                    foreach (KeyValuePair<string, string> header in headers)\n                    {\n                        req.SetRequestHeader(header.Key, header.Value);\n                    }\n                }\n\n                req.downloadHandler = new DownloadHandlerBuffer();\n                await req.SendWebRequest();\n\n#if UNITY_2020_1_OR_NEWER\n                if (req.result == UnityWebRequest.Result.ConnectionError || req.result == UnityWebRequest.Result.ProtocolError)\n#else\n                if (req.isNetworkError || req.isHttpError)\n#endif\n                {\n                    var errorMessage = req.error;\n\n                    if (!string.IsNullOrEmpty(req.downloadHandler.text))\n                    {\n                        try\n                        {\n                            var data = Json.Deserialize<ErrorResponse>(req.downloadHandler.text);\n                            if (!string.IsNullOrEmpty(data.error))\n                            {\n                                errorMessage = data.error;\n                            }\n                        }\n                        catch { }\n                    }\n\n                    throw new HttpException((int)req.responseCode, errorMessage);\n                }\n\n                return req.downloadHandler.text;\n            }\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityHttpClient.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3cf7b230495374a76948cb8b92393feb"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityLogger.cs",
    "content": "#if UNITY_5_3_OR_NEWER\nusing UnityEngine;\n\nnamespace Colyseus\n{\n    public class UnityLogger : ILogger\n    {\n        public void Log(string message)\n        {\n            Debug.Log(message);\n        }\n\n        public void LogWarning(string message)\n        {\n            Debug.LogWarning(message);\n        }\n\n        public void LogError(string message)\n        {\n            Debug.LogError(message);\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityLogger.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 641a11947d6ae4ca785718cc095a8422"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityPlatform.cs",
    "content": "#if UNITY_5_3_OR_NEWER\nusing UnityEngine;\n\nnamespace Colyseus\n{\n    /// <summary>\n    /// Auto-initializes ColyseusContext with Unity-specific implementations.\n    /// This runs before any scene loads, ensuring all Unity users get the correct platform bindings.\n    /// </summary>\n    public static class UnityPlatform\n    {\n        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]\n        public static void Initialize()\n        {\n            ColyseusContext.Logger = new UnityLogger();\n            ColyseusContext.HttpClient = new UnityHttpClient();\n            ColyseusContext.TokenStorage = new UnityTokenStorage();\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityPlatform.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 7f3783fa34f724310885d356cb346c8b"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnitySettings.cs",
    "content": "#if UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\nnamespace Colyseus\n{\n    /// <summary>\n    /// ScriptableObject wrapper around the core Settings POCO for Unity inspector compatibility.\n    /// Maintains backward compatibility with existing Unity projects that use Settings as a ScriptableObject.\n    /// </summary>\n    [CreateAssetMenu(fileName = \"MyServerSettings\", menuName = \"Colyseus/Server Settings Scriptable Object\", order = 1)]\n    [Serializable]\n    public class UnitySettings : ScriptableObject\n    {\n        /// <summary>\n        ///     The server address\n        /// </summary>\n        public string colyseusServerAddress = \"localhost\";\n\n        /// <summary>\n        ///     The port to connect to\n        /// </summary>\n        public string colyseusServerPort = \"2567\";\n\n        /// <summary>\n        ///     If true, we use secure protocols (wss, https) otherwise we use ws, http\n        /// </summary>\n        public bool useSecureProtocol = false;\n\n        [SerializeField]\n        private Settings.RequestHeader[] _requestHeaders;\n\n        /// <summary>\n        /// Convert this UnitySettings to a core Settings object\n        /// </summary>\n        public Settings ToSettings()\n        {\n            var settings = new Settings\n            {\n                colyseusServerAddress = colyseusServerAddress,\n                colyseusServerPort = colyseusServerPort,\n                useSecureProtocol = useSecureProtocol\n            };\n\n            if (_requestHeaders != null)\n            {\n                settings.SetRequestHeaders(_requestHeaders);\n            }\n\n            return settings;\n        }\n\n        /// <summary>\n        /// Implicit conversion to Settings for backward compatibility\n        /// </summary>\n        public static implicit operator Settings(UnitySettings unitySettings)\n        {\n            return unitySettings.ToSettings();\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnitySettings.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6d1d0994d204e41f2a1ad4fd8d0062a9"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityTokenStorage.cs",
    "content": "#if UNITY_5_3_OR_NEWER\nusing UnityEngine;\n\nnamespace Colyseus\n{\n    public class UnityTokenStorage : ITokenStorage\n    {\n        public string GetToken(string key)\n        {\n            return PlayerPrefs.GetString(key);\n        }\n\n        public void SetToken(string key, string value)\n        {\n            PlayerPrefs.SetString(key, value);\n        }\n\n        public void DeleteToken(string key)\n        {\n            PlayerPrefs.DeleteKey(key);\n        }\n    }\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity/UnityTokenStorage.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 49c288c14bb62415b8ccd07edc0fcae2"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform/Unity.meta",
    "content": "fileFormatVersion: 2\nguid: d570a06a0e1f64179a4e50e694ea47a5\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Platform.meta",
    "content": "fileFormatVersion: 2\nguid: 11ca095b9c22845eca472b0e5ae92d6d\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/ErrorCode.cs",
    "content": "// ReSharper disable InconsistentNaming\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Colyseus error codes mapping.\n    /// </summary>\n    public class ErrorCode\n    {\n\t    public static int MATCHMAKE_NO_HANDLER = 4210;\n\t    public static int MATCHMAKE_INVALID_CRITERIA = 4211;\n\t    public static int MATCHMAKE_INVALID_ROOM_ID = 4212;\n\t    public static int MATCHMAKE_UNHANDLED = 4213;\n\t    public static int MATCHMAKE_EXPIRED = 4214;\n\n\t    public static int AUTH_FAILED = 4215;\n\t    public static int APPLICATION_ERROR = 4216;\n\n\t    /// <summary>\n\t    ///     When local schema is different from schema on the server.\n\t    /// </summary>\n\t    public static int SCHEMA_MISMATCH = 4300;\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/ErrorCode.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 91ff24d8f9ec0420ebf7619585071190"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/MatchMakeResponse.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Wrapper class for a match making response\n    /// </summary>\n    /// <remarks>Returns room and sessionId if successful; code and error if not</remarks>\n    [Serializable]\n    public class SeatReservation\n    {\n        public string name;\n        public string sessionId;\n        public string roomId;\n        public string publicAddress;\n        public string processId;\n        public string reconnectionToken;\n        public bool devMode;\n        public string protocol;\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/MatchMakeResponse.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 96657d6a1a8244a298dd8bf4c14906c2"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/MessageHandler.cs",
    "content": "using System;\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Base interface for MessageHandlers\n    /// </summary>\n    public interface IMessageHandler\n    {\n        /// <summary>\n        ///     Message Type\n        /// </summary>\n        Type Type { get; }\n\n        /// <summary>\n        ///     Base invocation for the MessageHandler\n        /// </summary>\n        /// <param name=\"message\">The data to be passed into the function</param>\n        void Invoke(object message);\n    }\n\n    /// <summary>\n    ///     Base Implementation of the IMessageHandler interface\n    /// </summary>\n    /// <typeparam name=\"T\">Message Type</typeparam>\n    public class MessageHandler<T> : IMessageHandler\n    {\n        /// <summary>\n        ///     The Action this message will invoke\n        /// </summary>\n        public Action<T> Action;\n\n        /// <summary>\n        ///     Invokes this message's Action\n        /// </summary>\n        /// <param name=\"message\">Data for the Action, will be cast to \"T\"</param>\n        public void Invoke(object message)\n        {\n            Action.Invoke((T) message);\n        }\n\n        /// <summary>\n        ///     Implementation of the interface Type\n        /// </summary>\n        /// <returns>typeof(T)</returns>\n        public Type Type\n        {\n            get { return typeof(T); }\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/MessageHandler.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c67f9a6a0cc1b422195dd94a31f6e4e8"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/Protocol.cs",
    "content": "// ReSharper disable InconsistentNaming\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Colyseus server protocol codes mapping.\n    /// </summary>\n    public class Protocol\n    {\n        /// <summary>\n        ///     When client receives its unique id.\n        /// </summary>\n        public static byte USER_ID = 1;\n\n        //\n        // Room-related (9~19)\n        //\n\n        /// <summary>\n        ///     When JOIN is requested.\n        /// </summary>\n        public static byte JOIN_REQUEST = 9;\n\n        /// <summary>\n        ///     When JOIN request is accepted.\n        /// </summary>\n        public static byte JOIN_ROOM = 10;\n\n        /// <summary>\n        ///     When an error has happened in the server-side.\n        /// </summary>\n        public static byte ERROR = 11;\n\n        /// <summary>\n        ///     When server explicitly removes <see cref=\"Client\" /> from the <see cref=\"Room{T}\" />\n        /// </summary>\n        public static byte LEAVE_ROOM = 12;\n\n        /// <summary>\n        ///     When server sends data to a particular <see cref=\"Room{T}\" />\n        /// </summary>\n        public static byte ROOM_DATA = 13;\n\n        /// <summary>\n        ///     When server sends <see cref=\"Room{T}\" /> state to its clients.\n        /// </summary>\n        public static byte ROOM_STATE = 14;\n\n        /// <summary>\n        ///     When server sends <see cref=\"Room{T}\" /> state to its clients.\n        /// </summary>\n        public static byte ROOM_STATE_PATCH = 15;\n\n        /// <summary>\n        ///     When server sends a Schema-encoded message.\n        /// </summary>\n        public static byte ROOM_DATA_SCHEMA = 16;\n\n        public static byte ROOM_DATA_BYTES = 17;\n\n        /// <summary>\n        ///     Ping message for measuring round-trip latency.\n        /// </summary>\n        public static byte PING = 18;\n\n        //\n        // Matchmaking messages (20~30)\n        //\n        public static byte ROOM_LIST = 20;\n\n        //\n        // Generic messages (50~60)\n        //\n\n        /// <summary>\n        ///     When server doesn't understand a request, it returns <see cref=\"BAD_REQUEST\" /> to the <see cref=\"Client\" />\n        /// </summary>\n        public static byte BAD_REQUEST = 50;\n\n        // public Protocol (){}\n    }\n\n\tpublic enum CloseCode\n\t{\n\t\tNORMAL_CLOSURE = 1000,\n\t\tGOING_AWAY = 1001,\n\t\tNO_STATUS_RECEIVED = 1005,\n\t\tABNORMAL_CLOSURE = 1006,\n\t\tCONSENTED = 4000,\n\t\tSERVER_SHUTDOWN = 4001,\n\t\tWITH_ERROR = 4002,\n\t\tFAILED_TO_RECONNECT = 4003,\n\t\tMAY_TRY_RECONNECT = 4010,\n\t}\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/Protocol.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c8b23e2aef1384ae9af846c81bbe9b72"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/RoomAvailable.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Wrapper class for important, shorthand Room information\n    /// </summary>\n    [Serializable]\n    public class RoomAvailable\n    {\n        /// <summary>\n        ///     Current client count\n        /// </summary>\n        public int clients;\n\n        /// <summary>\n        ///     Maximum clients in this room (may be Infinity when unlimited)\n        /// </summary>\n        public double maxClients;\n\n        /// <summary>\n        ///     Room name\n        /// </summary>\n        public string name;\n\n        /// <summary>\n        ///     Public host address (optional)\n        /// </summary>\n        public string publicAddress;\n\n        /// <summary>\n        ///     Process ID used for connection\n        /// </summary>\n        public string processId;\n\n        /// <summary>\n        ///     Room ID\n        /// </summary>\n        public string roomId;\n\n        // public object metadata;\n    }\n\n    /// <summary>\n    ///     Get a collection of rooms\n    /// </summary>\n    /// <typeparam name=\"T\">Type of room inherited from <see cref=\"RoomAvailable\" /></typeparam>\n    [Serializable]\n    public class RoomAvailableCollection<T>\n    {\n        /// <summary>\n        ///     Rooms in this collection\n        /// </summary>\n        public T[] rooms;\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol/RoomAvailable.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 4844d7e0171e642b283b1c9bce462e70"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Protocol.meta",
    "content": "fileFormatVersion: 2\nguid: 1bde545c640ce40139e914607b757e39\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Room.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Colyseus.Schema;\nusing GameDevWare.Serialization;\n\nnamespace Colyseus\n{\n    using Decode = Schema.Utils.Decode;\n    using Encode = Schema.Utils.Encode;\n\n    public delegate void NoArgsEventHandler();\n\n    /// <summary>\n    ///     Delegate function for when <see cref=\"Client\" /> leaves this room.\n    /// </summary>\n    /// <param name=\"code\">Reason for closure</param>\n    public delegate void CloseWithCodeEventHandler(int code); // , string reason\n\n    /// <summary>\n    ///     Delegate function for when some error has been triggered in the room.\n    /// </summary>\n    /// <param name=\"code\">Error code</param>\n    /// <param name=\"message\">Error message</param>\n    public delegate void ErrorEventHandler(int code, string message);\n\n    /// <summary>\n    ///     Interface for functions expected of any <see cref=\"Room{T}\"></see>.\n    /// </summary>\n    public interface IRoom\n    {\n        event CloseWithCodeEventHandler OnLeave;\n\n        /// <summary>\n        ///     Connection task\n        /// </summary>\n        /// <returns>Task that completes upon connection (or failure to connect)</returns>\n        Task Connect();\n\n        /// <summary>\n        ///     Disconnection task\n        /// </summary>\n        /// <param name=\"consented\">True if by user's choice, false otherwise</param>\n        /// <returns>Task that completes upon Leaving</returns>\n        Task Leave(bool consented);\n    }\n\n    [Serializable]\n    public class ReconnectionToken\n    {\n        public string RoomId;\n        public string Token;\n    }\n\n    /// <summary>\n    ///     Configuration options for automatic reconnection behavior\n    /// </summary>\n    [Serializable]\n    public class ReconnectionOptions\n    {\n        /// <summary>\n        ///     Whether automatic reconnection is enabled.\n        ///     Set to false to disable automatic reconnection entirely.\n        /// </summary>\n        public bool Enabled = true;\n\n        /// <summary>\n        ///     The maximum number of reconnection attempts.\n        /// </summary>\n        public int MaxRetries = 15;\n\n        /// <summary>\n        ///     The minimum delay between reconnection attempts (in milliseconds).\n        /// </summary>\n        public int MinDelay = 100;\n\n        /// <summary>\n        ///     The maximum delay between reconnection attempts (in milliseconds).\n        /// </summary>\n        public int MaxDelay = 5000;\n\n        /// <summary>\n        ///     The minimum uptime of the room before reconnection attempts can be made (in milliseconds).\n        /// </summary>\n        public int MinUptime = 5000;\n\n        /// <summary>\n        ///     The current number of reconnection attempts.\n        /// </summary>\n        public int RetryCount = 0;\n\n        /// <summary>\n        ///     The initial delay between reconnection attempts (in milliseconds).\n        /// </summary>\n        public int Delay = 100;\n\n        /// <summary>\n        ///     Whether the room is currently reconnecting.\n        /// </summary>\n        public bool IsReconnecting = false;\n\n        /// <summary>\n        ///     The maximum number of enqueued messages to buffer.\n        /// </summary>\n        public int MaxEnqueuedMessages = 10;\n\n        /// <summary>\n        ///     Buffer for messages sent while connection is not open.\n        ///     These messages will be sent once the connection is re-established.\n        /// </summary>\n        public List<byte[]> EnqueuedMessages = new List<byte[]>();\n\n        /// <summary>\n        ///     The function to calculate the delay between reconnection attempts.\n        /// </summary>\n        public Func<int, int, int> Backoff = ExponentialBackoff;\n\n        /// <summary>\n        ///     Default exponential backoff function.\n        /// </summary>\n        /// <param name=\"attempt\">The current attempt number.</param>\n        /// <param name=\"delay\">The initial delay between reconnection attempts.</param>\n        /// <returns>The delay between reconnection attempts.</returns>\n        public static int ExponentialBackoff(int attempt, int delay)\n        {\n            return (int)Math.Floor(Math.Pow(2, attempt) * delay);\n        }\n    }\n\n    public class Room<T> : IRoom where T : Schema.Schema\n    {\n        /// <summary>\n        ///     Delegate for room state changes\n        /// </summary>\n        /// <param name=\"state\">The state change received</param>\n        /// <param name=\"isFirstState\">Flag if first state received</param>\n        public delegate void StateChangeEventHandler(T state, bool isFirstState);\n\n        /// <summary>\n        ///     Reference to the room's WebSocket Connection\n        /// </summary>\n        public Connection Connection;\n\n        /// <summary>\n        ///     Room ID\n        /// </summary>\n        public string RoomId;\n\n        /// <summary>\n        ///     Room name\n        /// </summary>\n        public string Name;\n\n        /// <summary>\n        ///     Dictionary of the message handlers that have been provided to the room\n        /// </summary>\n        protected Dictionary<string, IMessageHandler> OnMessageHandlers =\n            new Dictionary<string, IMessageHandler>();\n\n        /// <summary>\n        ///     Reference to the Serializer this room uses, determined and then generated based on the <see cref=\"SerializerId\" />\n        /// </summary>\n        internal ISerializer<T> Serializer;\n\n        /// <summary>\n        ///     ID to determine which kind of serializer this room uses (<see cref=\"SchemaSerializer{T}\" /> or\n        ///     <see cref=\"FossilDeltaSerializer\" />)\n        /// </summary>\n        public string SerializerId;\n\n        /// <summary>\n        ///     The room's session ID\n        /// </summary>\n        public string SessionId;\n\n        /// <summary>\n        ///     Reconnection Token for this room session. (must be provided for client.Reconnect())\n        /// </summary>\n        public ReconnectionToken ReconnectionToken;\n\n        /// <summary>\n        ///     Configuration options for automatic reconnection behavior.\n        /// </summary>\n        public ReconnectionOptions Reconnection = new ReconnectionOptions();\n\n        /// <summary>\n        ///     Timestamp when the room was joined (used for minUptime check).\n        /// </summary>\n        protected long JoinedAtTime = 0;\n\n        /// <summary>\n        ///     Timestamp of the last ping request (in milliseconds).\n        /// </summary>\n        private long _lastPingTime = 0;\n\n        /// <summary>\n        ///     Callback to invoke when ping response is received.\n        /// </summary>\n        private Action<int> _pingCallback = null;\n\n        /// <summary>\n        ///     Initializes a new instance of the <see cref=\"Room{T}\" /> class.\n        ///     It synchronizes state automatically with the server and send and receive messaes.\n        /// </summary>\n        /// <param name=\"name\">The Room identifier</param>\n        public Room(string name)\n        {\n            Name = name;\n\n            OnLeave += (code) => Destroy();\n\n#if UNITY_EDITOR\n            // Register handler for editor Room Inspector message type capture\n            // Uses reflection to avoid assembly reference from runtime to editor\n            OnMessage<Dictionary<string, object>>(\"__playground_message_types\", (messageTypes) =>\n            {\n                try\n                {\n                    var editorAssembly = System.Reflection.Assembly.Load(\"Colyseus.Editor\");\n                    if (editorAssembly != null)\n                    {\n                        var captureType = editorAssembly.GetType(\"Colyseus.Editor.RoomMessageType\");\n                        if (captureType != null)\n                        {\n                            var field = captureType.GetField(\"CapturedMessageTypes\",\n                                System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);\n                            if (field != null)\n                            {\n                                var dict = field.GetValue(null) as Dictionary<string, Dictionary<string, object>>;\n                                if (dict != null && !string.IsNullOrEmpty(RoomId))\n                                {\n                                    dict[RoomId] = messageTypes;\n                                }\n                            }\n                        }\n                    }\n                }\n                catch\n                {\n                    // Silently ignore if editor assembly is not available\n                }\n            });\n#endif\n        }\n\n        /// <summary>\n        ///     Getter for the <see cref=\"Room{T}\" />'s current state\n        /// </summary>\n        public T State\n        {\n            get { return Serializer.GetState(); }\n        }\n\n        [Obsolete(\".Id is deprecated. Please use .RoomId instead.\")]\n        public string Id\n        {\n            get { return RoomId; }\n        }\n\n        /// <summary>\n        ///     Occurs when <see cref=\"Client\" /> leaves this room.\n        /// </summary>\n        public event CloseWithCodeEventHandler OnLeave;\n\n        /// <summary>\n        ///     Implementation of <see cref=\"IRoom.Connect\" />\n        /// </summary>\n        /// <returns>Response from <see cref=\"Connection\"></see>.Connect()</returns>\n        public async Task Connect()\n        {\n            await Connection.Connect();\n        }\n\n        /// <summary>\n        ///     Leave the room\n        /// </summary>\n        /// <param name=\"consented\">If the user agreed to this disconnection</param>\n        /// <returns>Connection closure depending on user consent</returns>\n        public async Task Leave(bool consented = true)\n        {\n            if (!Connection.IsOpen) {\n                return;\n            }\n\n            if (RoomId != null)\n            {\n                var tcs = new TaskCompletionSource<int>();\n                void onLeave(int code) { tcs.TrySetResult(code); }\n                OnLeave += onLeave;\n\n                try\n                {\n                    if (consented)\n                    {\n                        await Connection.Send(new[] {Protocol.LEAVE_ROOM});\n                    }\n                    else\n                    {\n                        await Connection.Close();\n                    }\n                }\n                catch (OperationCanceledException)\n                {\n                    // Connection already dropped — leave will complete via OnLeave\n                }\n\n                try\n                {\n                    // Wait for the connection to fully close (with timeout to avoid hanging)\n                    await Task.WhenAny(tcs.Task, Task.Delay(5000));\n                }\n                finally\n                {\n                    OnLeave -= onLeave;\n                }\n            }\n            else\n            {\n                OnLeave?.Invoke((int)CloseCode.CONSENTED);\n            }\n        }\n\n        // Internal OnJoin event. It is used by Client.cs during matchmaking.\n        internal event NoArgsEventHandler OnJoin;\n\n        // <summary>\n        ///     Occurs when the room connection is dropped unexpectedly.\n\t\t///     Use to notify the user that a reconnection is being made.\n        /// </summary>\n        public event CloseWithCodeEventHandler OnDrop;\n\n        /// <summary>\n        ///     Occurs when automatically reconnected to the room after a connection drop.\n        /// </summary>\n        public event NoArgsEventHandler OnReconnect;\n\n        /// <summary>\n        ///     Occurs when some error has been triggered in the room.\n        /// </summary>\n        public event ErrorEventHandler OnError;\n\n        /// <summary>\n        ///     Occurs after applying the patched state on this <see cref=\"Room{T}\" />.\n        /// </summary>\n        public event StateChangeEventHandler OnStateChange;\n\n\t\t/// <summary>\n\t\t///     Called by the <see cref=\"Client\" /> upon connection to a room\n\t\t/// </summary>\n\t\t/// <param name=\"connection\">The connection created by the client</param>\n\t\tpublic void SetConnection(Connection connection)\n\t\t{\n\t        Connection = connection;\n\n\t        Connection.OnClose += code => {\n\t\t\t\tif (JoinedAtTime == 0) {\n\t\t\t\t\tOnError?.Invoke(code, \"Connection closed before joining room\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tcode == (int) CloseCode.NO_STATUS_RECEIVED ||\n\t\t\t\t\tcode == (int) CloseCode.ABNORMAL_CLOSURE ||\n\t\t\t\t\tcode == (int) CloseCode.GOING_AWAY ||\n\t\t\t\t\tcode == (int) CloseCode.MAY_TRY_RECONNECT\n\t\t\t\t) {\n\t\t\t\t\tOnDrop?.Invoke(code);\n\t\t\t\t\tHandleReconnection(code);\n\n\t\t\t\t} else {\n\t\t\t\t\tOnLeave?.Invoke(code);\n\t\t\t\t}\n\t        };\n\n\t        // TODO: expose WebSocket error code!\n\t        // Connection.OnError += (code, message) => OnError?.Invoke(code, message);\n\n\t        Connection.OnError += message => this.OnError?.Invoke(0, message);\n\t        Connection.OnMessage += bytes => this.ParseMessage(bytes);\n        }\n\n        /// <summary>\n        ///     Response to state changes received as messages\n        /// </summary>\n        /// ///\n        /// <remarks>Invokes everything subscribed to <see cref=\"OnStateChange\" /></remarks>\n        /// <param name=\"encodedState\">Byte array of the new state data</param>\n        /// <param name=\"offset\">Offset to provide the room's <see cref=\"Serializer\" /></param>\n        public void SetState(byte[] encodedState, int offset)\n        {\n            Serializer.SetState(encodedState, offset);\n            OnStateChange?.Invoke(Serializer.GetState(), true);\n        }\n\n        /// <summary>\n        ///     Send a message by number type, without payload\n        /// </summary>\n        /// <param name=\"type\">Message type</param>\n        public async Task Send(byte type)\n        {\n            byte[] bytes = new[] {Protocol.ROOM_DATA, type};\n\n            // If connection is not open, buffer the message\n            if (!Connection.IsOpen)\n            {\n                EnqueueMessage(bytes);\n                return;\n            }\n\n            await Connection.Send(bytes);\n        }\n\n        /// <summary>\n        ///     Send a message by number type with payload\n        /// </summary>\n        /// <param name=\"type\">Message type</param>\n        /// <param name=\"message\">Message payload</param>\n        public async Task Send(byte type, object message)\n        {\n            MemoryStream serializationOutput = new MemoryStream();\n            MsgPack.Serialize(message, serializationOutput, SerializationOptions.SuppressTypeInformation);\n\n            byte[] initialBytes = {Protocol.ROOM_DATA, type};\n            byte[] encodedMessage = serializationOutput.ToArray();\n\n            byte[] bytes = new byte[initialBytes.Length + encodedMessage.Length];\n            Buffer.BlockCopy(initialBytes, 0, bytes, 0, initialBytes.Length);\n            Buffer.BlockCopy(encodedMessage, 0, bytes, initialBytes.Length, encodedMessage.Length);\n\n            // If connection is not open, buffer the message\n            if (!Connection.IsOpen)\n            {\n                EnqueueMessage(bytes);\n                return;\n            }\n\n            await Connection.Send(bytes);\n        }\n\n        /// <summary>\n        ///     Send a message by string type, without payload\n        /// </summary>\n        /// <param name=\"type\">Message type</param>\n        public async Task Send(string type)\n        {\n            byte[] encodedType = Encoding.UTF8.GetBytes(type);\n            byte[] initialBytes = Encode.getInitialBytesFromEncodedType(encodedType, Protocol.ROOM_DATA);\n\n            byte[] bytes = new byte[initialBytes.Length + encodedType.Length];\n            Buffer.BlockCopy(initialBytes, 0, bytes, 0, initialBytes.Length);\n            Buffer.BlockCopy(encodedType, 0, bytes, initialBytes.Length, encodedType.Length);\n\n            // If connection is not open, buffer the message\n            if (!Connection.IsOpen)\n            {\n                EnqueueMessage(bytes);\n                return;\n            }\n\n            await Connection.Send(bytes);\n        }\n\n        /// <summary>\n        ///     Send a message by string type with payload\n        /// </summary>\n        /// <param name=\"type\">Message type</param>\n        /// <param name=\"message\">Message payload</param>\n        public async Task Send(string type, object message)\n        {\n            MemoryStream serializationOutput = new MemoryStream();\n            MsgPack.Serialize(message, serializationOutput, SerializationOptions.SuppressTypeInformation);\n\n            byte[] encodedType = Encoding.UTF8.GetBytes(type);\n            byte[] initialBytes = Encode.getInitialBytesFromEncodedType(encodedType, Protocol.ROOM_DATA);\n            byte[] encodedMessage = serializationOutput.ToArray();\n\n            byte[] bytes = new byte[encodedType.Length + encodedMessage.Length + initialBytes.Length];\n            Buffer.BlockCopy(initialBytes, 0, bytes, 0, initialBytes.Length);\n            Buffer.BlockCopy(encodedType, 0, bytes, initialBytes.Length, encodedType.Length);\n            Buffer.BlockCopy(encodedMessage, 0, bytes, initialBytes.Length + encodedType.Length, encodedMessage.Length);\n\n            // If connection is not open, buffer the message\n            if (!Connection.IsOpen)\n            {\n                EnqueueMessage(bytes);\n                return;\n            }\n\n            await Connection.Send(bytes);\n        }\n\n        /// <summary>\n        ///     Send a message by number type with raw bytes payload\n        /// </summary>\n        /// <param name=\"type\">Message type</param>\n        /// <param name=\"bytes\">Message payload</param>\n        public async Task SendBytes(byte type, byte[] bytes)\n        {\n            byte[] initialBytes = { Protocol.ROOM_DATA_BYTES, type };\n\n            byte[] bytesToSend = new byte[initialBytes.Length + bytes.Length];\n            Buffer.BlockCopy(initialBytes, 0, bytesToSend, 0, initialBytes.Length);\n            Buffer.BlockCopy(bytes, 0, bytesToSend, initialBytes.Length, bytes.Length);\n\n            // If connection is not open, buffer the message\n            if (!Connection.IsOpen)\n            {\n                EnqueueMessage(bytesToSend);\n                return;\n            }\n\n            await Connection.Send(bytesToSend);\n        }\n\n        /// <summary>\n        ///     Send a message by string type with raw bytes payload\n        /// </summary>\n        /// <param name=\"type\">Message type</param>\n        /// <param name=\"bytes\">Message payload</param>\n        public async Task SendBytes(string type, byte[] bytes)\n        {\n            byte[] encodedType = Encoding.UTF8.GetBytes(type);\n            byte[] initialBytes = Encode.getInitialBytesFromEncodedType(encodedType, Protocol.ROOM_DATA_BYTES);\n\n            byte[] bytesToSend = new byte[encodedType.Length + bytes.Length + initialBytes.Length];\n            Buffer.BlockCopy(initialBytes, 0, bytesToSend, 0, initialBytes.Length);\n            Buffer.BlockCopy(encodedType, 0, bytesToSend, initialBytes.Length, encodedType.Length);\n            Buffer.BlockCopy(bytes, 0, bytesToSend, initialBytes.Length + encodedType.Length, bytes.Length);\n\n            // If connection is not open, buffer the message\n            if (!Connection.IsOpen)\n            {\n                EnqueueMessage(bytesToSend);\n                return;\n            }\n\n            await Connection.Send(bytesToSend);\n        }\n\n        /// <summary>\n        ///     Send a ping to the server and measure round-trip latency.\n        /// </summary>\n        /// <param name=\"callback\">Callback invoked with the round-trip time in milliseconds</param>\n        public async void Ping(Action<int> callback)\n        {\n            // Skip if connection is not open\n            if (Connection == null || !Connection.IsOpen)\n            {\n                return;\n            }\n\n            _lastPingTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n            _pingCallback = callback;\n            await Connection.Send(new[] { Protocol.PING });\n        }\n\n        /// <summary>\n        ///     Method to add new message handlers to the room\n        /// </summary>\n        /// <param name=\"type\">The type of message received</param>\n        /// <param name=\"handler\"></param>\n        /// <typeparam name=\"MessageType\">The type of object this message should respond with</typeparam>\n        public void OnMessage<MessageType>(string type, Action<MessageType> handler)\n        {\n            OnMessageHandlers.Add(type, new MessageHandler<MessageType>\n            {\n                Action = handler\n            });\n        }\n\n        /// <summary>\n        ///     Method to add new message handlers to the room\n        /// </summary>\n        /// <param name=\"type\">The type of message received</param>\n        /// <param name=\"handler\"></param>\n        /// <typeparam name=\"MessageType\">The type of object this message should respond with</typeparam>\n        public void OnMessage<MessageType>(byte type, Action<MessageType> handler)\n        {\n            OnMessageHandlers.Add(\"i\" + type, new MessageHandler<MessageType>\n            {\n                Action = handler\n            });\n        }\n\n        /// <summary>\n        ///     The function that will be called when the <see cref=\"Connection\" /> receives a message\n        /// </summary>\n        /// <param name=\"bytes\">The message as provided from the <see cref=\"Connection\" /></param>\n        protected async void ParseMessage(byte[] bytes)\n        {\n            byte code = bytes[0];\n\n            if (code == Protocol.JOIN_ROOM)\n            {\n                int offset = 1;\n\n                var reconnectionToken = Encoding.UTF8.GetString(bytes, offset + 1, bytes[offset]);\n                offset += reconnectionToken.Length + 1;\n\n                SerializerId = Encoding.UTF8.GetString(bytes, offset + 1, bytes[offset]);\n                offset += SerializerId.Length + 1;\n\n                if (SerializerId == \"schema\")\n                {\n                    try\n                    {\n                        Serializer = new SchemaSerializer<T>();\n                    }\n                    catch (Exception e)\n                    {\n                        DisplaySerializerErrorHelp(e,\n                            \"Consider using the \\\"schema-codegen\\\" and providing the same room state for matchmaking instead of \\\"\" +\n                            typeof(T).Name + \"\\\"\");\n                    }\n                }\n                else if (SerializerId == \"fossil-delta\")\n                {\n                    ColyseusContext.Logger.LogError(\n                        \"FossilDelta Serialization has been deprecated. It is highly recommended that you update your code to use the Schema Serializer. Otherwise, you must use an earlier version of the Colyseus plugin\");\n                }\n                else\n                {\n                    Serializer = (ISerializer<T>) new NoneSerializer();\n                }\n\n                if (bytes.Length > offset)\n                {\n\t                try {\n\t\t                Serializer.Handshake(bytes, offset);\n\t                }\n\t                catch (Exception e)\n\t                {\n\t\t                await Leave(false);\n\t\t                OnError?.Invoke(ErrorCode.SCHEMA_MISMATCH, e.Message);\n\t\t                return;\n\t                }\n                }\n\n                ReconnectionToken = new ReconnectionToken()\n                {\n                    RoomId = RoomId,\n                    Token = reconnectionToken\n                };\n\n                if (JoinedAtTime == 0)\n                {\n                    // First time joining\n                    JoinedAtTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n                    OnJoin?.Invoke();\n                }\n                else\n                {\n                    // Successful reconnection\n                    ColyseusContext.Logger.Log(\"[Colyseus reconnection]: Reconnection successful!\");\n                    Reconnection.IsReconnecting = false;\n                    OnReconnect?.Invoke();\n                }\n\n                // Acknowledge JOIN_ROOM\n                await Connection.Send(new[] {Protocol.JOIN_ROOM});\n\n                // Flush any enqueued messages that were buffered while disconnected\n                await FlushEnqueuedMessages();\n            }\n            else if (code == Protocol.ERROR)\n            {\n                Iterator it = new Iterator {Offset = 1};\n                float errorCode = Decode.DecodeNumber(bytes, it);\n                string errorMessage = Decode.DecodeString(bytes, it);\n                OnError?.Invoke((int) errorCode, errorMessage);\n            }\n            else if (code == Protocol.LEAVE_ROOM)\n            {\n                await Leave();\n            }\n            else if (code == Protocol.ROOM_STATE)\n            {\n\t            SetState(bytes, 1);\n            }\n            else if (code == Protocol.ROOM_STATE_PATCH)\n            {\n                Patch(bytes, 1);\n            }\n            else if (code == Protocol.PING)\n            {\n                long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n                _pingCallback?.Invoke((int)(now - _lastPingTime));\n                _pingCallback = null;\n            }\n            else if (code == Protocol.ROOM_DATA || code == Protocol.ROOM_DATA_BYTES)\n            {\n                IMessageHandler handler = null;\n                object type;\n\n                Iterator it = new Iterator {Offset = 1};\n\n                if (Decode.NumberCheck(bytes, it))\n                {\n                    type = Decode.DecodeNumber(bytes, it);\n                    OnMessageHandlers.TryGetValue(\"i\" + type, out handler);\n                }\n                else\n                {\n                    type = Decode.DecodeString(bytes, it);\n                    OnMessageHandlers.TryGetValue(type.ToString(), out handler);\n                }\n\n                if (handler != null)\n                {\n                    object message = null;\n\n                    if ( code == Protocol.ROOM_DATA )\n                    {\n                        //\n                        // MsgPack deserialization can be optimized:\n                        // https://github.com/deniszykov/msgpack-unity3d/issues/23\n                        //\n                        message = bytes.Length > it.Offset\n                            ? MsgPack.Deserialize(handler.Type,\n                                new MemoryStream(bytes, it.Offset, bytes.Length - it.Offset, false))\n                            : null;\n                    }\n                    else if ( code == Protocol.ROOM_DATA_BYTES )\n                    {\n                        message = new byte[bytes.Length - it.Offset];\n                        Buffer.BlockCopy(bytes, it.Offset, (byte[])message, 0, bytes.Length - it.Offset);\n                    }\n\n                    handler.Invoke(message);\n                }\n                else if (type != null && !type.ToString().StartsWith(\"__\"))\n                {\n                    ColyseusContext.Logger.LogWarning(\"room.OnMessage() not registered for: '\" + type + \"'\");\n                }\n            }\n        }\n\n        /// <summary>\n        ///     Update the state with just the new changes to the state\n        /// </summary>\n        /// <remarks>Invokes everything subscribed to <see cref=\"OnStateChange\" /></remarks>\n        /// <param name=\"delta\">The updates to the state</param>\n        /// <param name=\"offset\">Offset to provide the room's <see cref=\"Serializer\" /></param>\n        protected void Patch(byte[] delta, int offset)\n        {\n            Serializer.Patch(delta, offset);\n            OnStateChange?.Invoke(Serializer.GetState(), false);\n        }\n\n        /// <summary>\n        ///     Helper function to display errors with de-serializing messages from server\n        /// </summary>\n        /// <param name=\"e\">Exception information</param>\n        /// <param name=\"helpMessage\">Additional information to display</param>\n        /// <exception cref=\"Exception\">Throws <paramref name=\"e\" /></exception>\n        protected void DisplaySerializerErrorHelp(Exception e, string helpMessage)\n        {\n            ColyseusContext.Logger.LogWarning(\"The serializer from the server is: '\" + SerializerId + \"'. \" + helpMessage);\n            throw e;\n        }\n\n\t\tprivate void HandleReconnection(int code)\n\t\t{\n\t\t\tif (!Reconnection.Enabled)\n\t\t\t{\n\t\t\t\tOnLeave?.Invoke(code);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check minimum uptime before allowing reconnection\n\t\t\tlong currentTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n\t\t\tif (currentTime - JoinedAtTime < Reconnection.MinUptime)\n\t\t\t{\n\t\t\t\tColyseusContext.Logger.Log($\"[Colyseus reconnection]: Room not up long enough for auto-reconnect (min uptime: {Reconnection.MinUptime}ms)\");\n\t\t\t\tOnLeave?.Invoke((int)CloseCode.ABNORMAL_CLOSURE);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!Reconnection.IsReconnecting)\n\t\t\t{\n\t\t\t\tReconnection.RetryCount = 0;\n\t\t\t\tReconnection.IsReconnecting = true;\n\t\t\t}\n\n\t\t\t_ = RetryReconnection();\n\t\t}\n\n\t\tprivate async Task RetryReconnection()\n\t\t{\n\t\t\tif (Reconnection.RetryCount >= Reconnection.MaxRetries)\n\t\t\t{\n\t\t\t\t// No more retries\n\t\t\t\tColyseusContext.Logger.Log($\"[Colyseus reconnection]: Reconnection failed after {Reconnection.MaxRetries} attempts.\");\n\t\t\t\tReconnection.IsReconnecting = false;\n\t\t\t\tOnLeave?.Invoke((int)CloseCode.FAILED_TO_RECONNECT);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tReconnection.RetryCount++;\n\n\t\t\tint delay = Math.Min(Reconnection.MaxDelay,\n\t\t\t\tMath.Max(Reconnection.MinDelay,\n\t\t\t\t\tReconnection.Backoff(Reconnection.RetryCount, Reconnection.Delay)));\n\n\t\t\tColyseusContext.Logger.Log($\"[Colyseus reconnection]: Will retry in {delay / 1000f:F1} seconds...\");\n\t\t\tawait Task.Delay(delay);\n\n\t\t\tColyseusContext.Logger.Log($\"[Colyseus reconnection]: Re-establishing sessionId '{SessionId}' with roomId '{RoomId}'... (attempt {Reconnection.RetryCount} of {Reconnection.MaxRetries})\");\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Connection.Reconnect(ReconnectionToken.Token);\n\t\t\t}\n\t\t\tcatch (Exception e)\n\t\t\t{\n\t\t\t\tColyseusContext.Logger.Log($\"[Colyseus reconnection]: Reconnect failed - {e.Message}\");\n\t\t\t\t_ = RetryReconnection();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Enqueue a message to be sent when the connection is re-established.\n\t\t/// </summary>\n\t\t/// <param name=\"data\">The message data to enqueue</param>\n\t\tprivate void EnqueueMessage(byte[] data)\n\t\t{\n\t\t\tReconnection.EnqueuedMessages.Add(data);\n\t\t\tif (Reconnection.EnqueuedMessages.Count > Reconnection.MaxEnqueuedMessages)\n\t\t\t{\n\t\t\t\tReconnection.EnqueuedMessages.RemoveAt(0);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Flush all enqueued messages after reconnection.\n\t\t/// </summary>\n\t\tprivate async Task FlushEnqueuedMessages()\n\t\t{\n\t\t\tif (Reconnection.EnqueuedMessages.Count == 0) return;\n\n\t\t\tforeach (var message in Reconnection.EnqueuedMessages)\n\t\t\t{\n\t\t\t\tawait Connection.Send(message);\n\t\t\t}\n\t\t\tReconnection.EnqueuedMessages.Clear();\n\t\t}\n\n\t\tprivate void Destroy()\n\t\t{\n\t\t\tSerializer.Teardown();\n\t\t}\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Room.cs.meta",
    "content": "fileFormatVersion: 2\nguid: b196046f3733f4667a642ce7d71263ae"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/BigEndianBitConverter.cs",
    "content": "/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see \nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse \nor promote products derived from this software without prior written \npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called \n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE. \n*/\n\nnamespace MiscUtil.Conversion\n{\n\t/// <summary>\n\t/// Implementation of EndianBitConverter which converts to/from big-endian\n\t/// byte arrays.\n\t/// </summary>\n\tpublic sealed class BigEndianBitConverter : EndianBitConverter\n\t{\n\t\t/// <summary>\n\t\t/// Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Different computer architectures store data using different byte orders. \"Big-endian\"\n\t\t/// means the most significant byte is on the left end of a word. \"Little-endian\" means the \n\t\t/// most significant byte is on the right end of a word.\n\t\t/// </remarks>\n\t\t/// <returns>true if this converter is little-endian, false otherwise.</returns>\n\t\tpublic sealed override bool IsLittleEndian()\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\tpublic sealed override Endianness Endianness \n\t\t{ \n\t\t\tget { return Endianness.BigEndian; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified number of bytes from value to buffer, starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy</param>\n\t\t/// <param name=\"bytes\">The number of bytes to copy</param>\n\t\t/// <param name=\"buffer\">The buffer to copy the bytes into</param>\n\t\t/// <param name=\"index\">The index to start at</param>\n\t\tprotected override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)\n\t\t{\n\t\t\tint endOffset = index+bytes-1;\n\t\t\tfor (int i=0; i < bytes; i++)\n\t\t\t{\n\t\t\t\tbuffer[endOffset-i] = unchecked((byte)(value&0xff));\n\t\t\t\tvalue = value >> 8;\n\t\t\t}\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Returns a value built from the specified number of bytes from the given buffer,\n\t\t/// starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"buffer\">The data in byte array format</param>\n\t\t/// <param name=\"startIndex\">The first index to use</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to use</param>\n\t\t/// <returns>The value built from the given bytes</returns>\n\t\tprotected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)\n\t\t{\n\t\t\tlong ret = 0;\n\t\t\tfor (int i=0; i < bytesToConvert; i++)\n\t\t\t{\n\t\t\t\tret = unchecked((ret << 8) | buffer[startIndex+i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/BigEndianBitConverter.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d2db5d6cc28318447a02c83fcba42a1f\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/DoubleConverter.cs",
    "content": "/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see \nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse \nor promote products derived from this software without prior written \npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called \n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE. \n*/\n\nusing System;\nusing System.Globalization;\n\nnamespace MiscUtil.Conversion\n{\n\t/// <summary>\n\t/// A class to allow the conversion of doubles to string representations of\n\t/// their exact decimal values. The implementation aims for readability over\n\t/// efficiency.\n\t/// </summary>\n\tpublic class DoubleConverter\n\t{    \n\t\t/// <summary>\n\t\t/// Converts the given double to a string representation of its\n\t\t/// exact decimal value.\n\t\t/// </summary>\n\t\t/// <param name=\"d\">The double to convert.</param>\n\t\t/// <returns>A string representation of the double's exact decimal value.</returns>\n\t\tpublic static string ToExactString (double d)\n\t\t{\n\t\t\tif (double.IsPositiveInfinity(d))\n\t\t\t\treturn \"+Infinity\";\n\t\t\tif (double.IsNegativeInfinity(d))\n\t\t\t\treturn \"-Infinity\";\n\t\t\tif (double.IsNaN(d))\n\t\t\t\treturn \"NaN\";\n\n\t\t\t// Translate the double into sign, exponent and mantissa.\n\t\t\tlong bits = BitConverter.DoubleToInt64Bits(d);\n\t\t\tbool negative = (bits < 0);\n\t\t\tint exponent = (int) ((bits >> 52) & 0x7ffL);\n\t\t\tlong mantissa = bits & 0xfffffffffffffL;\n\n\t\t\t// Subnormal numbers; exponent is effectively one higher,\n\t\t\t// but there's no extra normalisation bit in the mantissa\n\t\t\tif (exponent==0)\n\t\t\t{\n\t\t\t\texponent++;\n\t\t\t}\n\t\t\t// Normal numbers; leave exponent as it is but add extra\n\t\t\t// bit to the front of the mantissa\n\t\t\telse\n\t\t\t{\n\t\t\t\tmantissa = mantissa | (1L<<52);\n\t\t\t}\n\t        \n\t\t\t// Bias the exponent. It's actually biased by 1023, but we're\n\t\t\t// treating the mantissa as m.0 rather than 0.m, so we need\n\t\t\t// to subtract another 52 from it.\n\t\t\texponent -= 1075;\n\t        \n\t\t\tif (mantissa == 0) \n\t\t\t{\n\t\t\t\treturn \"0\";\n\t\t\t}\n\t        \n\t\t\t/* Normalize */\n\t\t\twhile((mantissa & 1) == 0) \n\t\t\t{    /*  i.e., Mantissa is even */\n\t\t\t\tmantissa >>= 1;\n\t\t\t\texponent++;\n\t\t\t}\n\t        \n\t\t\t// Construct a new decimal expansion with the mantissa\n\t\t\tArbitraryDecimal ad = new ArbitraryDecimal (mantissa);\n\t        \n\t\t\t// If the exponent is less than 0, we need to repeatedly\n\t\t\t// divide by 2 - which is the equivalent of multiplying\n\t\t\t// by 5 and dividing by 10.\n\t\t\tif (exponent < 0) \n\t\t\t{\n\t\t\t\tfor (int i=0; i < -exponent; i++)\n\t\t\t\t\tad.MultiplyBy(5);\n\t\t\t\tad.Shift(-exponent);\n\t\t\t} \n\t\t\t\t// Otherwise, we need to repeatedly multiply by 2\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (int i=0; i < exponent; i++)\n\t\t\t\t\tad.MultiplyBy(2);\n\t\t\t}\n\t        \n\t\t\t// Finally, return the string with an appropriate sign\n\t\t\tif (negative)\n\t\t\t\treturn \"-\"+ad.ToString();\n\t\t\telse\n\t\t\t\treturn ad.ToString();\n\t\t}\n\t    \n\t\t/// <summary>\n\t\t/// Private class used for manipulating sequences of decimal digits.\n\t\t/// </summary>\n\t\tclass ArbitraryDecimal\n\t\t{\n\t\t\t/// <summary>Digits in the decimal expansion, one byte per digit</summary>\n\t\t\tbyte[] digits;\n\t\t\t/// <summary> \n\t\t\t/// How many digits are *after* the decimal point\n\t\t\t/// </summary>\n\t\t\tint decimalPoint=0;\n\n\t\t\t/// <summary> \n\t\t\t/// Constructs an arbitrary decimal expansion from the given long.\n\t\t\t/// The long must not be negative.\n\t\t\t/// </summary>\n\t\t\tinternal ArbitraryDecimal (long x)\n\t\t\t{\n\t\t\t\tstring tmp = x.ToString(CultureInfo.InvariantCulture);\n\t\t\t\tdigits = new byte[tmp.Length];\n\t\t\t\tfor (int i=0; i < tmp.Length; i++)\n\t\t\t\t\tdigits[i] = (byte) (tmp[i]-'0');\n\t\t\t\tNormalize();\n\t\t\t}\n\t        \n\t\t\t/// <summary>\n\t\t\t/// Multiplies the current expansion by the given amount, which should\n\t\t\t/// only be 2 or 5.\n\t\t\t/// </summary>\n\t\t\tinternal void MultiplyBy(int amount)\n\t\t\t{\n\t\t\t\tbyte[] result = new byte[digits.Length+1];\n\t\t\t\tfor (int i=digits.Length-1; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tint resultDigit = digits[i]*amount+result[i+1];\n\t\t\t\t\tresult[i]=(byte)(resultDigit/10);\n\t\t\t\t\tresult[i+1]=(byte)(resultDigit%10);\n\t\t\t\t}\n\t\t\t\tif (result[0] != 0)\n\t\t\t\t{\n\t\t\t\t\tdigits=result;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tArray.Copy (result, 1, digits, 0, digits.Length);\n\t\t\t\t}\n\t\t\t\tNormalize();\n\t\t\t}\n\t        \n\t\t\t/// <summary>\n\t\t\t/// Shifts the decimal point; a negative value makes\n\t\t\t/// the decimal expansion bigger (as fewer digits come after the\n\t\t\t/// decimal place) and a positive value makes the decimal\n\t\t\t/// expansion smaller.\n\t\t\t/// </summary>\n\t\t\tinternal void Shift (int amount)\n\t\t\t{\n\t\t\t\tdecimalPoint += amount;\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Removes leading/trailing zeroes from the expansion.\n\t\t\t/// </summary>\n\t\t\tinternal void Normalize()\n\t\t\t{\n\t\t\t\tint first;\n\t\t\t\tfor (first=0; first < digits.Length; first++)\n\t\t\t\t\tif (digits[first]!=0)\n\t\t\t\t\t\tbreak;\n\t\t\t\tint last;\n\t\t\t\tfor (last=digits.Length-1; last >= 0; last--)\n\t\t\t\t\tif (digits[last]!=0)\n\t\t\t\t\t\tbreak;\n\t            \n\t\t\t\tif (first==0 && last==digits.Length-1)\n\t\t\t\t\treturn;\n\t            \n\t\t\t\tbyte[] tmp = new byte[last-first+1];\n\t\t\t\tfor (int i=0; i < tmp.Length; i++)\n\t\t\t\t\ttmp[i]=digits[i+first];\n\t            \n\t\t\t\tdecimalPoint -= digits.Length-(last+1);\n\t\t\t\tdigits=tmp;\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Converts the value to a proper decimal string representation.\n\t\t\t/// </summary>\n\t\t\tpublic override String ToString()\n\t\t\t{\n\t\t\t\tchar[] digitString = new char[digits.Length];            \n\t\t\t\tfor (int i=0; i < digits.Length; i++)\n\t\t\t\t\tdigitString[i] = (char)(digits[i]+'0');\n\t            \n\t\t\t\t// Simplest case - nothing after the decimal point,\n\t\t\t\t// and last real digit is non-zero, eg value=35\n\t\t\t\tif (decimalPoint==0)\n\t\t\t\t{\n\t\t\t\t\treturn new string (digitString);\n\t\t\t\t}\n\t            \n\t\t\t\t// Fairly simple case - nothing after the decimal\n\t\t\t\t// point, but some 0s to add, eg value=350\n\t\t\t\tif (decimalPoint < 0)\n\t\t\t\t{\n\t\t\t\t\treturn new string (digitString)+\n\t\t\t\t\t\tnew string ('0', -decimalPoint);\n\t\t\t\t}\n\t            \n\t\t\t\t// Nothing before the decimal point, eg 0.035\n\t\t\t\tif (decimalPoint >= digitString.Length)\n\t\t\t\t{\n\t\t\t\t\treturn \"0.\"+\n\t\t\t\t\t\tnew string ('0',(decimalPoint-digitString.Length))+\n\t\t\t\t\t\tnew string (digitString);\n\t\t\t\t}\n\n\t\t\t\t// Most complicated case - part of the string comes\n\t\t\t\t// before the decimal point, part comes after it,\n\t\t\t\t// eg 3.5\n\t\t\t\treturn new string (digitString, 0, \n\t\t\t\t\tdigitString.Length-decimalPoint)+\n\t\t\t\t\t\".\"+\n\t\t\t\t\tnew string (digitString,\n\t\t\t\t\tdigitString.Length-decimalPoint, \n\t\t\t\t\tdecimalPoint);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/DoubleConverter.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c7daa1e51f7f668468924517b6446fe9\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/EndianBitConverter.cs",
    "content": "/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see \nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse \nor promote products derived from this software without prior written \npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called \n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE. \n*/\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace MiscUtil.Conversion\n{\n\t/// <summary>\n\t/// Equivalent of System.BitConverter, but with either endianness.\n\t/// </summary>\n\tpublic abstract class EndianBitConverter\n\t{\n\t\t#region Endianness of this converter\n\t\t/// <summary>\n\t\t/// Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Different computer architectures store data using different byte orders. \"Big-endian\"\n\t\t/// means the most significant byte is on the left end of a word. \"Little-endian\" means the \n\t\t/// most significant byte is on the right end of a word.\n\t\t/// </remarks>\n\t\t/// <returns>true if this converter is little-endian, false otherwise.</returns>\n\t\tpublic abstract bool IsLittleEndian();\n\n\t\t/// <summary>\n\t\t/// Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\tpublic abstract Endianness Endianness { get; }\n\t\t#endregion\n\n\t\t#region Factory properties\n\t\tstatic LittleEndianBitConverter little = new LittleEndianBitConverter();\n\t\t/// <summary>\n\t\t/// Returns a little-endian bit converter instance. The same instance is\n\t\t/// always returned.\n\t\t/// </summary>\n\t\tpublic static LittleEndianBitConverter Little\n\t\t{\n\t\t\tget { return little; }\n\t\t}\n\n\t\tstatic BigEndianBitConverter big = new BigEndianBitConverter();\n\t\t/// <summary>\n\t\t/// Returns a big-endian bit converter instance. The same instance is\n\t\t/// always returned.\n\t\t/// </summary>\n\t\tpublic static BigEndianBitConverter Big\n\t\t{\n\t\t\tget { return big; }\n\t\t}\n\t\t#endregion\n\n\t\t#region Double/primitive conversions\n\t\t/// <summary>\n\t\t/// Converts the specified double-precision floating point number to a \n\t\t/// 64-bit signed integer. Note: the endianness of this converter does not\n\t\t/// affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A 64-bit signed integer whose value is equivalent to value.</returns>\n\t\tpublic long DoubleToInt64Bits(double value)\n\t\t{\n\t\t\treturn BitConverter.DoubleToInt64Bits(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the specified 64-bit signed integer to a double-precision \n\t\t/// floating point number. Note: the endianness of this converter does not\n\t\t/// affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A double-precision floating point number whose value is equivalent to value.</returns>\n\t\tpublic double Int64BitsToDouble (long value)\n\t\t{\n\t\t\treturn BitConverter.Int64BitsToDouble(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the specified single-precision floating point number to a \n\t\t/// 32-bit signed integer. Note: the endianness of this converter does not\n\t\t/// affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A 32-bit signed integer whose value is equivalent to value.</returns>\n\t\tpublic int SingleToInt32Bits(float value)\n\t\t{\n\t\t\treturn new Int32SingleUnion(value).AsInt32;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the specified 32-bit signed integer to a single-precision floating point \n\t\t/// number. Note: the endianness of this converter does not\n\t\t/// affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A single-precision floating point number whose value is equivalent to value.</returns>\n\t\tpublic float Int32BitsToSingle (int value)\n\t\t{\n\t\t\treturn new Int32SingleUnion(value).AsSingle;\n\t\t}\n\t\t#endregion\n\n\t\t#region To(PrimitiveType) conversions\n\t\t/// <summary>\n\t\t/// Returns a Boolean value converted from one byte at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>true if the byte at startIndex in value is nonzero; otherwise, false.</returns>\n\t\tpublic bool ToBoolean (byte[] value, int startIndex)\n\t\t{\n\t\t\tCheckByteArgument(value, startIndex, 1);\n\t\t\treturn BitConverter.ToBoolean(value, startIndex);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a Unicode character converted from two bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A character formed by two bytes beginning at startIndex.</returns>\n\t\tpublic char ToChar (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((char) (CheckedFromBytes(value, startIndex, 2)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a double-precision floating point number converted from eight bytes \n\t\t/// at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A double precision floating point number formed by eight bytes beginning at startIndex.</returns>\n\t\tpublic double ToDouble (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn Int64BitsToDouble(ToInt64(value, startIndex));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a single-precision floating point number converted from four bytes \n\t\t/// at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A single precision floating point number formed by four bytes beginning at startIndex.</returns>\n\t\tpublic float ToSingle (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn Int32BitsToSingle(ToInt32(value, startIndex));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 16-bit signed integer formed by two bytes beginning at startIndex.</returns>\n\t\tpublic short ToInt16 (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((short) (CheckedFromBytes(value, startIndex, 2)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 32-bit signed integer formed by four bytes beginning at startIndex.</returns>\n\t\tpublic int ToInt32 (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((int) (CheckedFromBytes(value, startIndex, 4)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 64-bit signed integer formed by eight bytes beginning at startIndex.</returns>\n\t\tpublic long ToInt64 (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn CheckedFromBytes(value, startIndex, 8);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>\n\t\tpublic ushort ToUInt16 (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((ushort) (CheckedFromBytes(value, startIndex, 2)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>\n\t\tpublic uint ToUInt32 (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((uint) (CheckedFromBytes(value, startIndex, 4)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 64-bit unsigned integer formed by eight bytes beginning at startIndex.</returns>\n\t\tpublic ulong ToUInt64 (byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((ulong) (CheckedFromBytes(value, startIndex, 8)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Checks the given argument for validity.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The byte array passed in</param>\n\t\t/// <param name=\"startIndex\">The start index passed in</param>\n\t\t/// <param name=\"bytesRequired\">The number of bytes required</param>\n\t\t/// <exception cref=\"ArgumentNullException\">value is a null reference</exception>\n\t\t/// <exception cref=\"ArgumentOutOfRangeException\">\n\t\t/// startIndex is less than zero or greater than the length of value minus bytesRequired.\n\t\t/// </exception>\n\t\tstatic void CheckByteArgument(byte[] value, int startIndex, int bytesRequired)\n\t\t{\n\t\t\tif (value==null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(\"value\");\n\t\t\t}\n\t\t\tif (startIndex < 0 || startIndex > value.Length-bytesRequired)\n\t\t\t{\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"startIndex\");\n\t\t\t}\n\t\t}\n\n        /// <summary>\n        /// Checks the arguments for validity before calling FromBytes\n        /// (which can therefore assume the arguments are valid).\n        /// </summary>\n        /// <param name=\"value\">The bytes to convert after checking</param>\n        /// <param name=\"startIndex\">The index of the first byte to convert</param>\n        /// <param name=\"bytesToConvert\">The number of bytes to convert</param>\n        /// <returns></returns>\n\t\tlong CheckedFromBytes(byte[] value, int startIndex, int bytesToConvert)\n\t\t{\n\t\t\tCheckByteArgument(value, startIndex, bytesToConvert);\n\t\t\treturn FromBytes(value, startIndex, bytesToConvert);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Convert the given number of bytes from the given array, from the given start\n\t\t/// position, into a long, using the bytes as the least significant part of the long.\n\t\t/// By the time this is called, the arguments have been checked for validity.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The bytes to convert</param>\n\t\t/// <param name=\"startIndex\">The index of the first byte to convert</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to use in the conversion</param>\n\t\t/// <returns>The converted number</returns>\n\t\tprotected abstract long FromBytes(byte[] value, int startIndex, int bytesToConvert);\n\t\t#endregion\n\n\t\t#region ToString conversions\n\t\t/// <summary>\n\t\t/// Returns a String converted from the elements of a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <remarks>All the elements of value are converted.</remarks>\n\t\t/// <returns>\n\t\t/// A String of hexadecimal pairs separated by hyphens, where each pair \n\t\t/// represents the corresponding element in value; for example, \"7F-2C-4A\".\n\t\t/// </returns>\n\t\tpublic static string ToString(byte[] value)\n\t\t{\n\t\t\treturn BitConverter.ToString(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a String converted from the elements of a byte array starting at a specified array position.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <remarks>The elements from array position startIndex to the end of the array are converted.</remarks>\n\t\t/// <returns>\n\t\t/// A String of hexadecimal pairs separated by hyphens, where each pair \n\t\t/// represents the corresponding element in value; for example, \"7F-2C-4A\".\n\t\t/// </returns>\n\t\tpublic static string ToString(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn BitConverter.ToString(value, startIndex);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a String converted from a specified number of bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <param name=\"length\">The number of bytes to convert.</param>\n\t\t/// <remarks>The length elements from array position startIndex are converted.</remarks>\n\t\t/// <returns>\n\t\t/// A String of hexadecimal pairs separated by hyphens, where each pair \n\t\t/// represents the corresponding element in value; for example, \"7F-2C-4A\".\n\t\t/// </returns>\n\t\tpublic static string ToString(byte[] value, int startIndex, int length)\n\t\t{\n\t\t\treturn BitConverter.ToString(value, startIndex, length);\n\t\t}\n\t\t#endregion\n\n\t\t#region\tDecimal conversions\n\t\t/// <summary>\n\t\t/// Returns a decimal value converted from sixteen bytes \n\t\t/// at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A decimal  formed by sixteen bytes beginning at startIndex.</returns>\n\t\tpublic decimal ToDecimal (byte[] value, int startIndex)\n\t\t{\n\t\t\t// HACK: This always assumes four parts, each in their own endianness,\n\t\t\t// starting with the first part at the start of the byte array.\n\t\t\t// On the other hand, there's no real format specified...\n\t\t\tint[] parts = new int[4];\n\t\t\tfor (int i=0; i < 4; i++)\n\t\t\t{\n\t\t\t\tparts[i] = ToInt32(value, startIndex+i*4);\n\t\t\t}\n\t\t\treturn new Decimal(parts);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified decimal value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 16.</returns>\n\t\tpublic byte[] GetBytes(decimal value)\n\t\t{\n\t\t\tbyte[] bytes = new byte[16];\n\t\t\tint[] parts = decimal.GetBits(value);\n\t\t\tfor (int i=0; i < 4; i++)\n\t\t\t{\n\t\t\t\tCopyBytesImpl(parts[i], 4, bytes, i*4);\n\t\t\t}\n\t\t\treturn bytes;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified decimal value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A character to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(decimal value, byte[] buffer, int index)\n\t\t{\n\t\t\tint[] parts = decimal.GetBits(value);\n\t\t\tfor (int i=0; i < 4; i++)\n\t\t\t{\n\t\t\t\tCopyBytesImpl(parts[i], 4, buffer, i*4+index);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetBytes conversions\n\t\t/// <summary>\n\t\t/// Returns an array with the given number of bytes formed\n\t\t/// from the least significant bytes of the specified value.\n\t\t/// This is used to implement the other GetBytes methods.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to get bytes for</param>\n\t\t/// <param name=\"bytes\">The number of significant bytes to return</param>\n\t\tbyte[] GetBytes(long value, int bytes)\n\t\t{\n\t\t\tbyte[] buffer = new byte[bytes];\n\t\t\tCopyBytes(value, bytes, buffer, 0);\n\t\t\treturn buffer;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified Boolean value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A Boolean value.</param>\n\t\t/// <returns>An array of bytes with length 1.</returns>\n\t\tpublic byte[] GetBytes(bool value)\n\t\t{\n\t\t\treturn BitConverter.GetBytes(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified Unicode character value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A character to convert.</param>\n\t\t/// <returns>An array of bytes with length 2.</returns>\n\t\tpublic byte[] GetBytes(char value)\n\t\t{\n\t\t\treturn GetBytes(value, 2);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified double-precision floating point value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 8.</returns>\n\t\tpublic byte[] GetBytes(double value)\n\t\t{\n\t\t\treturn GetBytes(DoubleToInt64Bits(value), 8);\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Returns the specified 16-bit signed integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 2.</returns>\n\t\tpublic byte[] GetBytes(short value)\n\t\t{\n\t\t\treturn GetBytes(value, 2);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified 32-bit signed integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 4.</returns>\n\t\tpublic byte[] GetBytes(int value)\n\t\t{\n\t\t\treturn GetBytes(value, 4);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified 64-bit signed integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 8.</returns>\n\t\tpublic byte[] GetBytes(long value)\n\t\t{\n\t\t\treturn GetBytes(value, 8);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified single-precision floating point value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 4.</returns>\n\t\tpublic byte[] GetBytes(float value)\n\t\t{\n\t\t\treturn GetBytes(SingleToInt32Bits(value), 4);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified 16-bit unsigned integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 2.</returns>\n\t\tpublic byte[] GetBytes(ushort value)\n\t\t{\n\t\t\treturn GetBytes(value, 2);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified 32-bit unsigned integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 4.</returns>\n\t\tpublic byte[] GetBytes(uint value)\n\t\t{\n\t\t\treturn GetBytes(value, 4);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the specified 64-bit unsigned integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 8.</returns>\n\t\tpublic byte[] GetBytes(ulong value)\n\t\t{\n\t\t\treturn GetBytes(unchecked((long)value), 8);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region CopyBytes conversions\n\t\t/// <summary>\n\t\t/// Copies the given number of bytes from the least-specific\n\t\t/// end of the specified value into the specified byte array, beginning\n\t\t/// at the specified index.\n\t\t/// This is used to implement the other CopyBytes methods.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy bytes for</param>\n\t\t/// <param name=\"bytes\">The number of significant bytes to copy</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tvoid CopyBytes(long value, int bytes, byte[] buffer, int index)\n\t\t{\n\t\t\tif (buffer==null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(\"buffer\", \"Byte array must not be null\");\n\t\t\t}\n\t\t\tif (buffer.Length < index+bytes)\n\t\t\t{\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"Buffer not big enough for value\");\n\t\t\t}\n\t\t\tCopyBytesImpl(value, bytes, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the given number of bytes from the least-specific\n\t\t/// end of the specified value into the specified byte array, beginning\n\t\t/// at the specified index.\n\t\t/// This must be implemented in concrete derived classes, but the implementation\n\t\t/// may assume that the value will fit into the buffer.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy bytes for</param>\n\t\t/// <param name=\"bytes\">The number of significant bytes to copy</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tprotected abstract void CopyBytesImpl(long value, int bytes, byte[] buffer, int index);\n\n\t\t/// <summary>\n\t\t/// Copies the specified Boolean value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A Boolean value.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(bool value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value ? 1 : 0, 1, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified Unicode character value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A character to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(char value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 2, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified double-precision floating point value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(double value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(DoubleToInt64Bits(value), 8, buffer, index);\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Copies the specified 16-bit signed integer value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(short value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 2, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified 32-bit signed integer value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(int value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 4, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified 64-bit signed integer value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(long value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 8, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified single-precision floating point value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(float value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(SingleToInt32Bits(value), 4, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified 16-bit unsigned integer value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(ushort value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 2, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified 32-bit unsigned integer value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(uint value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 4, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified 64-bit unsigned integer value into the specified byte array,\n\t\t/// beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(ulong value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(unchecked((long)value), 8, buffer, index);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Private struct used for Single/Int32 conversions\n\t\t/// <summary>\n\t\t/// Union used solely for the equivalent of DoubleToInt64Bits and vice versa.\n\t\t/// </summary>\n\t\t[StructLayout(LayoutKind.Explicit)]\n\t\t\tstruct Int32SingleUnion\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// Int32 version of the value.\n\t\t\t/// </summary>\n\t\t\t[FieldOffset(0)]\n\t\t\tint i;\n\t\t\t/// <summary>\n\t\t\t/// Single version of the value.\n\t\t\t/// </summary>\n\t\t\t[FieldOffset(0)]\n\t\t\tfloat f;\n\n\t\t\t/// <summary>\n\t\t\t/// Creates an instance representing the given integer.\n\t\t\t/// </summary>\n\t\t\t/// <param name=\"i\">The integer value of the new instance.</param>\n\t\t\tinternal Int32SingleUnion(int i)\n\t\t\t{\n\t\t\t\tthis.f = 0; // Just to keep the compiler happy\n\t\t\t\tthis.i = i;\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Creates an instance representing the given floating point number.\n\t\t\t/// </summary>\n\t\t\t/// <param name=\"f\">The floating point value of the new instance.</param>\n\t\t\tinternal Int32SingleUnion(float f)\n\t\t\t{\n\t\t\t\tthis.i = 0; // Just to keep the compiler happy\n\t\t\t\tthis.f = f;\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Returns the value of the instance as an integer.\n\t\t\t/// </summary>\n\t\t\tinternal int AsInt32\n\t\t\t{\n\t\t\t\tget { return i; }\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Returns the value of the instance as a floating point number.\n\t\t\t/// </summary>\n\t\t\tinternal float AsSingle\n\t\t\t{\n\t\t\t\tget { return f; }\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/EndianBitConverter.cs.meta",
    "content": "fileFormatVersion: 2\nguid: aa6dd963847f2e6408c89a530095710a\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/Endianness.cs",
    "content": "/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see \nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse \nor promote products derived from this software without prior written \npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called \n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE. \n*/\n\nnamespace MiscUtil.Conversion\n{\n\t/// <summary>\n\t/// Endianness of a converter\n\t/// </summary>\n\tpublic enum Endianness\n\t{\n\t\t/// <summary>\n\t\t/// Little endian - least significant byte first\n\t\t/// </summary>\n\t\tLittleEndian,\n\t\t/// <summary>\n\t\t/// Big endian - most significant byte first\n\t\t/// </summary>\n\t\tBigEndian\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/Endianness.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8885dda9cbb1c6246840582b6c637300\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/LittleEndianBitConverter.cs",
    "content": "/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see \nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse \nor promote products derived from this software without prior written \npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called \n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE. \n*/\n\nnamespace MiscUtil.Conversion\n{\n\t/// <summary>\n\t/// Implementation of EndianBitConverter which converts to/from little-endian\n\t/// byte arrays.\n\t/// </summary>\n\tpublic sealed class LittleEndianBitConverter : EndianBitConverter\n\t{\n\t\t/// <summary>\n\t\t/// Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Different computer architectures store data using different byte orders. \"Big-endian\"\n\t\t/// means the most significant byte is on the left end of a word. \"Little-endian\" means the \n\t\t/// most significant byte is on the right end of a word.\n\t\t/// </remarks>\n\t\t/// <returns>true if this converter is little-endian, false otherwise.</returns>\n\t\tpublic sealed override bool IsLittleEndian()\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\tpublic sealed override Endianness Endianness \n\t\t{ \n\t\t\tget { return Endianness.LittleEndian; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies the specified number of bytes from value to buffer, starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy</param>\n\t\t/// <param name=\"bytes\">The number of bytes to copy</param>\n\t\t/// <param name=\"buffer\">The buffer to copy the bytes into</param>\n\t\t/// <param name=\"index\">The index to start at</param>\n\t\tprotected override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)\n\t\t{\n\t\t\tfor (int i=0; i < bytes; i++)\n\t\t\t{\n\t\t\t\tbuffer[i+index] = unchecked((byte)(value&0xff));\n\t\t\t\tvalue = value >> 8;\n\t\t\t}\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Returns a value built from the specified number of bytes from the given buffer,\n\t\t/// starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"buffer\">The data in byte array format</param>\n\t\t/// <param name=\"startIndex\">The first index to use</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to use</param>\n\t\t/// <returns>The value built from the given bytes</returns>\n\t\tprotected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)\n\t\t{\n\t\t\tlong ret = 0;\n\t\t\tfor (int i=0; i < bytesToConvert; i++)\n\t\t\t{\n\t\t\t\tret = unchecked((ret << 8) | buffer[startIndex+bytesToConvert-1-i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion/LittleEndianBitConverter.cs.meta",
    "content": "fileFormatVersion: 2\nguid: dfe60c6da8d01634ab384a42243791ad\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Conversion.meta",
    "content": "fileFormatVersion: 2\nguid: 3825dca9a7fae88429eff0ef4538364d\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/NoneSerializer.cs",
    "content": "namespace Colyseus\n{\n    // TODO: remove dummy state dependency from NoneSerializer.\n    public class NoState : Schema.Schema { }\n\n    /// <summary>\n    ///     An empty implementation of <see cref=\"ISerializer{T}\" />\n    /// </summary>\n    public class NoneSerializer : ISerializer<NoState>\n    {\n        NoState state = new NoState();\n\n        /// <inheritdoc />\n        public void SetState(byte[] rawEncodedState, int offset)\n        {\n        }\n\n        /// <inheritdoc />\n        public NoState GetState()\n        {\n            return state;\n        }\n\n        /// <inheritdoc />\n        public void Patch(byte[] bytes, int offset)\n        {\n        }\n\n        /// <inheritdoc />\n        public void Teardown()\n        {\n        }\n\n        /// <inheritdoc />\n        public void Handshake(byte[] bytes, int offset)\n        {\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/NoneSerializer.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ad9bf8bd4c18f480ca4fe0084bf21d92\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Callbacks/Callbacks.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\n\nnamespace Colyseus.Schema\n{\n\t/// <summary>\n\t///     Helper class to extract property chains from nested member expressions\n\t/// </summary>\n\tinternal static class ExpressionHelper\n\t{\n\t\t/// <summary>\n\t\t///     Extracts the property chain from a nested member expression.\n\t\t///     For example, `state => state.staticEntities.entities` returns [\"staticEntities\", \"entities\"]\n\t\t/// </summary>\n\t\tpublic static List<string> GetPropertyChain(Expression expression)\n\t\t{\n\t\t\tvar chain = new List<string>();\n\t\t\tvar current = expression;\n\n\t\t\twhile (current is MemberExpression memberExpr)\n\t\t\t{\n\t\t\t\tchain.Insert(0, memberExpr.Member.Name);\n\t\t\t\tcurrent = memberExpr.Expression;\n\t\t\t}\n\n\t\t\treturn chain;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Gets the root instance from an expression by walking up to the parameter.\n\t\t/// </summary>\n\t\tpublic static Expression GetRootExpression(Expression expression)\n\t\t{\n\t\t\tvar current = expression;\n\t\t\twhile (current is MemberExpression memberExpr)\n\t\t\t{\n\t\t\t\tcurrent = memberExpr.Expression;\n\t\t\t}\n\t\t\treturn current;\n\t\t}\n\t}\n\n\t/// <summary>\n\t///     Delegate for handling events given a <paramref name=\"key\" /> and a <paramref name=\"value\" />\n\t/// </summary>\n\t/// <typeparam name=\"T\"></typeparam>\n\t/// <param name=\"currentValue\"></param>\n\t/// <param name=\"previousValue\"></param>\n\tpublic delegate void PropertyChangeEventHandler<T>(T currentValue, T previousValue);\n\n\t/// <summary>\n\t///     Delegate function when any property on the schema structure has changed.\n\t/// </summary>\n\tpublic delegate void OnInstanceChangeEventHandler();\n\n\t/// <summary>\n\t///     Delegate function for handling <see cref=\"Schema\" /> removal\n\t/// </summary>\n\tpublic delegate void OnRemoveEventHandler();\n\n\t/// <summary>\n\t///     Delegate for handling events given a <paramref name=\"key\" /> and a <paramref name=\"value\" />\n\t/// </summary>\n\t/// <param name=\"value\">The affected value</param>\n\t/// <param name=\"key\">The key we're affecting</param>\n\t/// <typeparam name=\"K\">The type of <see cref=\"object\" /> we're attempting to access</typeparam>\n\t/// <typeparam name=\"T\">The <see cref=\"Schema\" /> type</typeparam>\n\tpublic delegate void KeyValueEventHandler<K, T>(K key, T value);\n\n\tpublic class StateCallbackStrategy<TState>\n\t\twhere TState : Schema\n\t{\n\t\tprotected Decoder<TState> Decoder;\n\n\t\tprotected HashSet<int> UniqueRefIds = new HashSet<int>();\n\n\t\tprotected bool isTriggering = false;\n\n\t\tpublic StateCallbackStrategy(Decoder<TState> decoder)\n\t\t{\n\t\t\tDecoder = decoder;\n\t\t\tDecoder.TriggerChanges = TriggerChanges;\n\t\t}\n\n\t\tprotected Action AddCallback(int refId, object operationOrProperty, Delegate handler)\n\t\t{\n\t\t\tif (!Decoder.Refs.callbacks.TryGetValue(refId, out var handlers))\n\t\t\t{\n\t\t\t\thandlers = new Dictionary<object, List<Delegate>>();\n\t\t\t\tDecoder.Refs.callbacks[refId] = handlers;\n\t\t\t}\n\t\t\tif (!handlers.ContainsKey(operationOrProperty))\n\t\t\t{\n\t\t\t\thandlers[operationOrProperty] = new List<Delegate>();\n\t\t\t}\n\t\t\thandlers[operationOrProperty].Add(handler);\n\t\t\treturn () => handlers[operationOrProperty].Remove(handler);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Navigates through a nested property chain and invokes a callback when the final property is reached.\n\t\t///     Automatically listens to intermediate properties and re-attaches handlers when they change.\n\t\t/// </summary>\n\t\t/// <param name=\"instance\">The root instance to start navigation from</param>\n\t\t/// <param name=\"propertyChain\">List of property names to navigate through</param>\n\t\t/// <param name=\"currentIndex\">Current position in the property chain</param>\n\t\t/// <param name=\"onFinalProperty\">Callback invoked with the final Schema instance and property name</param>\n\t\t/// <param name=\"immediate\">Whether to trigger immediately if available</param>\n\t\t/// <returns>Action to remove all attached listeners</returns>\n\t\tprotected Action NavigateNestedProperties(Schema instance, List<string> propertyChain, int currentIndex, Func<Schema, string, Action> onFinalProperty, bool immediate = true)\n\t\t{\n\t\t\tif (currentIndex >= propertyChain.Count)\n\t\t\t{\n\t\t\t\treturn () => { };\n\t\t\t}\n\n\t\t\tvar propertyName = propertyChain[currentIndex];\n\t\t\tvar isLastProperty = currentIndex == propertyChain.Count - 1;\n\n\t\t\tif (isLastProperty)\n\t\t\t{\n\t\t\t\t// We've reached the final property, invoke the callback\n\t\t\t\treturn onFinalProperty(instance, propertyName);\n\t\t\t}\n\n\t\t\t// We're at an intermediate property, need to navigate deeper\n\t\t\tAction removeHandler = () => { };\n\t\t\tAction removeListener = () => removeHandler();\n\n\t\t\tvar currentValue = instance[propertyName];\n\n\t\t\tif (currentValue == null)\n\t\t\t{\n\t\t\t\t// Intermediate property not available yet, listen for it\n\t\t\t\tremoveHandler = AddCallback(instance.__refId, propertyName, new PropertyChangeEventHandler<Schema>((newValue, prevValue) =>\n\t\t\t\t{\n\t\t\t\t\t// Remove previous deep listener if any\n\t\t\t\t\tremoveHandler();\n\n\t\t\t\t\tif (newValue != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Navigate to the next level\n\t\t\t\t\t\tremoveHandler = NavigateNestedProperties(newValue, propertyChain, currentIndex + 1, onFinalProperty, immediate);\n\t\t\t\t\t}\n\t\t\t\t}));\n\t\t\t}\n\t\t\telse if (currentValue is Schema schemaValue)\n\t\t\t{\n\t\t\t\t// Intermediate property is available, navigate deeper\n\t\t\t\tremoveHandler = NavigateNestedProperties(schemaValue, propertyChain, currentIndex + 1, onFinalProperty, immediate);\n\n\t\t\t\t// Also listen for changes to re-attach handlers\n\t\t\t\tvar removeChangeListener = AddCallback(instance.__refId, propertyName, new PropertyChangeEventHandler<Schema>((newValue, prevValue) =>\n\t\t\t\t{\n\t\t\t\t\t// Remove previous deep listener\n\t\t\t\t\tremoveHandler();\n\n\t\t\t\t\tif (newValue != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Navigate to the next level with the new value\n\t\t\t\t\t\tremoveHandler = NavigateNestedProperties(newValue, propertyChain, currentIndex + 1, onFinalProperty, immediate);\n\t\t\t\t\t}\n\t\t\t\t}));\n\n\t\t\t\tvar originalRemoveHandler = removeHandler;\n\t\t\t\tremoveHandler = () =>\n\t\t\t\t{\n\t\t\t\t\toriginalRemoveHandler();\n\t\t\t\t\tremoveChangeListener();\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn removeListener;\n\t\t}\n\n\t\tprotected Action AddCallbackOrWaitCollectionAvailable<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, TReturn>> propertyExpression, OPERATION operation, Delegate handler, bool immediate = true)\n\t\t\twhere TInstance : Schema\n\t\t\twhere TReturn : IRef\n\t\t{\n\t\t\tvar propertyChain = ExpressionHelper.GetPropertyChain(propertyExpression.Body);\n\n\t\t\t// If only one property in chain, use the original simple logic\n\t\t\tif (propertyChain.Count == 1)\n\t\t\t{\n\t\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyChain[0], operation, handler, immediate);\n\t\t\t}\n\n\t\t\t// For nested properties, use the navigation helper\n\t\t\tAction removeHandler = () => { };\n\t\t\tAction removeAll = () => removeHandler();\n\n\t\t\tremoveHandler = NavigateNestedProperties(instance, propertyChain, 0, (finalInstance, finalPropertyName) =>\n\t\t\t{\n\t\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(finalInstance, finalPropertyName, operation, handler, immediate);\n\t\t\t}, immediate);\n\n\t\t\treturn removeAll;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Original simple implementation for single-level property access\n\t\t/// </summary>\n\t\tprotected Action AddCallbackOrWaitCollectionAvailableSimple(Schema instance, string propertyName, OPERATION operation, Delegate handler, bool immediate = true)\n\t\t{\n\t\t\tAction removeHandler = () => { };\n\t\t\tAction removeOnAdd = () => removeHandler();\n\n\t\t\t// Collection not available yet. Listen for its availability before attaching the handler.\n\t\t\tif (instance[propertyName] == null)\n\t\t\t{\n\t\t\t\tAction removePropertyCallback = null;\n\t\t\t\tremovePropertyCallback = AddCallback(instance.__refId, propertyName, new PropertyChangeEventHandler<IRef>((IRef collection, IRef _) =>\n\t\t\t\t{\n\t\t\t\t\tif (collection != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Remove the property listener now that collection is available\n\t\t\t\t\t\tremovePropertyCallback();\n\t\t\t\t\t\tremoveHandler = AddCallback(collection.__refId, operation, handler);\n\t\t\t\t\t}\n\t\t\t\t}));\n\t\t\t\tremoveHandler = removePropertyCallback;\n\t\t\t\treturn removeOnAdd;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t//\n\t\t\t\t// Call immediately if collection is already available, if it's an ADD operation.\n\t\t\t\t//\n\t\t\t\timmediate = immediate && isTriggering == false;\n\n\t\t\t\tif (operation == OPERATION.ADD && immediate)\n\t\t\t\t{\n\t\t\t\t\t((ISchemaCollection)instance[propertyName]).ForEach((key, value) =>\n\t\t\t\t\t{\n\t\t\t\t\t\thandler.DynamicInvoke(key, value);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn AddCallback(((IRef)instance[propertyName]).__refId, operation, handler);\n\t\t\t}\n\t\t}\n\n\t\tpublic Action Listen<TReturn>(Expression<Func<TState, TReturn>> propertyExpression, PropertyChangeEventHandler<TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn Listen(Decoder.State, propertyExpression, handler, immediate);\n\t\t}\n\n\t\tpublic Action Listen<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, TReturn>> propertyExpression, PropertyChangeEventHandler<TReturn> handler, bool immediate = true)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\tvar propertyChain = ExpressionHelper.GetPropertyChain(propertyExpression.Body);\n\n\t\t\t// If only one property in chain, use the original simple logic\n\t\t\tif (propertyChain.Count == 1)\n\t\t\t{\n\t\t\t\treturn ListenSimple(instance, propertyChain[0], handler, immediate);\n\t\t\t}\n\n\t\t\t// For nested properties, use the navigation helper\n\t\t\tAction removeHandler = () => { };\n\t\t\tAction removeAll = () => removeHandler();\n\n\t\t\tremoveHandler = NavigateNestedProperties(instance, propertyChain, 0, (finalInstance, finalPropertyName) =>\n\t\t\t{\n\t\t\t\treturn ListenSimple(finalInstance, finalPropertyName, handler, immediate);\n\t\t\t}, immediate);\n\n\t\t\treturn removeAll;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Original simple implementation for single-level property listening\n\t\t/// </summary>\n\t\tprotected Action ListenSimple<TReturn>(Schema instance, string propertyName, PropertyChangeEventHandler<TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\timmediate = immediate && isTriggering == false;\n\n\t\t\t//\n\t\t\t// Call handler immediately if property is already available.\n\t\t\t//\n\t\t\tif (immediate && instance[propertyName] != null && !instance[propertyName].Equals(default(TReturn)))\n\t\t\t{\n\t\t\t\thandler((TReturn)instance[propertyName], default(TReturn));\n\t\t\t}\n\n\t\t\treturn AddCallback(instance.__refId, propertyName, handler);\n\t\t}\n\n\t\tpublic Action OnChange<T>(T instance, OnInstanceChangeEventHandler handler)\n\t\t\twhere T : Schema\n\t\t{\n\t\t\treturn AddCallback(instance.__refId, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\tpublic Action OnAdd<TReturn>(Expression<Func<TState, ArraySchema<TReturn>>> propertyExpression, KeyValueEventHandler<int, TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn OnAdd(Decoder.State, propertyExpression, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, ArraySchema<TReturn>>> propertyExpression, KeyValueEventHandler<int, TReturn> handler, bool immediate = true)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailable(instance, propertyExpression, OPERATION.ADD, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TReturn>(Expression<Func<TState, MapSchema<TReturn>>> propertyExpression, KeyValueEventHandler<string, TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn OnAdd(Decoder.State, propertyExpression, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, MapSchema<TReturn>>> propertyExpression, KeyValueEventHandler<string, TReturn> handler, bool immediate = true)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailable(instance, propertyExpression, OPERATION.ADD, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnChange<TReturn>(Expression<Func<TState, ArraySchema<TReturn>>> propertyExpression, KeyValueEventHandler<int, TReturn> handler)\n\t\t{\n\t\t\treturn OnChange(Decoder.State, propertyExpression, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, ArraySchema<TReturn>>> propertyExpression, KeyValueEventHandler<int, TReturn> handler)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailable(instance, propertyExpression, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TReturn>(Expression<Func<TState, MapSchema<TReturn>>> propertyExpression, KeyValueEventHandler<string, TReturn> handler)\n\t\t{\n\t\t\treturn OnChange(Decoder.State, propertyExpression, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, MapSchema<TReturn>>> propertyExpression, KeyValueEventHandler<string, TReturn> handler)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailable(instance, propertyExpression, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TReturn>(Expression<Func<TState, ArraySchema<TReturn>>> propertyExpression, KeyValueEventHandler<int, TReturn> handler)\n\t\t{\n\t\t\treturn OnRemove(Decoder.State, propertyExpression, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, ArraySchema<TReturn>>> propertyExpression, KeyValueEventHandler<int, TReturn> handler)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailable(instance, propertyExpression, OPERATION.DELETE, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TReturn>(Expression<Func<TState, MapSchema<TReturn>>> propertyExpression, KeyValueEventHandler<string, TReturn> handler)\n\t\t{\n\t\t\treturn OnRemove(Decoder.State, propertyExpression, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TInstance, TReturn>(TInstance instance, Expression<Func<TInstance, MapSchema<TReturn>>> propertyExpression, KeyValueEventHandler<string, TReturn> handler)\n\t\t\twhere TInstance : Schema\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailable(instance, propertyExpression, OPERATION.DELETE, handler);\n\t\t}\n\n\t\t//\n\t\t// String-based overloads (for DynamicSchema / untyped access)\n\t\t//\n\n\t\tpublic Action Listen<TReturn>(string propertyName, PropertyChangeEventHandler<TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn ListenSimple(Decoder.State, propertyName, handler, immediate);\n\t\t}\n\n\t\tpublic Action Listen<TReturn>(Schema instance, string propertyName, PropertyChangeEventHandler<TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn ListenSimple(instance, propertyName, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TReturn>(string propertyName, KeyValueEventHandler<string, TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(Decoder.State, propertyName, OPERATION.ADD, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TReturn>(Schema instance, string propertyName, KeyValueEventHandler<string, TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyName, OPERATION.ADD, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TReturn>(string propertyName, KeyValueEventHandler<int, TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(Decoder.State, propertyName, OPERATION.ADD, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnAdd<TReturn>(Schema instance, string propertyName, KeyValueEventHandler<int, TReturn> handler, bool immediate = true)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyName, OPERATION.ADD, handler, immediate);\n\t\t}\n\n\t\tpublic Action OnRemove<TReturn>(string propertyName, KeyValueEventHandler<string, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(Decoder.State, propertyName, OPERATION.DELETE, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TReturn>(Schema instance, string propertyName, KeyValueEventHandler<string, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyName, OPERATION.DELETE, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TReturn>(string propertyName, KeyValueEventHandler<int, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(Decoder.State, propertyName, OPERATION.DELETE, handler);\n\t\t}\n\n\t\tpublic Action OnRemove<TReturn>(Schema instance, string propertyName, KeyValueEventHandler<int, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyName, OPERATION.DELETE, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TReturn>(string propertyName, KeyValueEventHandler<string, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(Decoder.State, propertyName, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TReturn>(Schema instance, string propertyName, KeyValueEventHandler<string, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyName, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TReturn>(string propertyName, KeyValueEventHandler<int, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(Decoder.State, propertyName, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\tpublic Action OnChange<TReturn>(Schema instance, string propertyName, KeyValueEventHandler<int, TReturn> handler)\n\t\t{\n\t\t\treturn AddCallbackOrWaitCollectionAvailableSimple(instance, propertyName, OPERATION.REPLACE, handler);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// \tBinds a schema property to a target object.\n\t\t/// </summary>\n\t\t/// <param name=\"instance\"></param>\n\t\t/// <param name=\"target\"></param>\n\t\t/// <returns></returns>\n\t\tpublic Action BindTo<T>(Schema from, T to, bool immediate = true)\n\t\t{\n\t\t\tvar action = (Action)(() =>\n\t\t\t{\n\t\t\t\tvar toType = typeof(T);\n\t\t\t\tforeach (var field in from.fieldsByIndex)\n\t\t\t\t{\n\t\t\t\t\tvar fromValue = from.GetType().GetProperty(field.Value)?.GetValue(from);\n\t\t\t\t\tvar toProperty = toType.GetProperty(field.Value);\n\n\t\t\t\t\tif (toProperty != null && fromValue != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (toProperty.PropertyType.IsAssignableFrom(fromValue.GetType()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoProperty.SetValue(to, fromValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Handle type mismatch, maybe convert or log\n\t\t\t\t\t\t\tColyseusContext.Logger.Log($\"BindTo: Type mismatch for property {field.Value}: Cannot assign {fromValue.GetType().Name} to {toProperty.PropertyType.Name}\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (immediate) {\n\t\t\t\taction();\n\t\t\t}\n\t\t\treturn AddCallback(from.__refId, to, action);\n\t\t}\n\n\t\tprotected void TriggerChanges(ref List<DataChange> allChanges)\n\t\t{\n\t\t\tUniqueRefIds.Clear();\n\n\t\t\tforeach (DataChange change in allChanges)\n\t\t\t{\n\t\t\t\tvar refId = change.RefId;\n\t\t\t\tvar _ref = Decoder.Refs.Get(refId);\n\n\t\t\t\t// Dictionary<object, List<Delegate>> callbacks = Decoder.Refs.callbacks[refId];\n\t\t\t\tDecoder.Refs.callbacks.TryGetValue(refId, out var callbacks);\n\n\t\t\t\tif (callbacks == null)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t//\n\t\t\t\t// trigger onRemove on child structure.\n\t\t\t\t//\n\t\t\t\tif ((change.Op & (byte)OPERATION.DELETE) == (byte)OPERATION.DELETE && change.PreviousValue is Schema)\n\t\t\t\t{\n\t\t\t\t\tDecoder.Refs.callbacks.TryGetValue(((Schema)change.PreviousValue).__refId, out var deleteCallbacks);\n\t\t\t\t\tif (deleteCallbacks != null\n\t\t\t\t\t    && deleteCallbacks.ContainsKey(OPERATION.DELETE)\n\t\t\t\t\t    && deleteCallbacks[OPERATION.DELETE] != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var callback in deleteCallbacks[OPERATION.DELETE])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcallback.DynamicInvoke();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (_ref is Schema)\n\t\t\t\t{\n\t\t\t\t\t//\n\t\t\t\t\t// Handle Schema instance\n\t\t\t\t\t//\n\n\t\t\t\t\tif (!UniqueRefIds.Contains(refId))\n\t\t\t\t\t{\n\t\t\t\t\t\t// trigger onChange\n\t\t\t\t\t\tcallbacks.TryGetValue(OPERATION.REPLACE, out var replaceCallbacks);\n\t\t\t\t\t\tif (replaceCallbacks != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var callback in replaceCallbacks)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcallback.DynamicInvoke();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (Exception e)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tColyseusContext.Logger.LogError(e.Message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallbacks.TryGetValue(change.Field, out var fieldCallbacks);\n\t\t\t\t\tif (fieldCallbacks != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// iterate a copy — deferred listeners may remove themselves during iteration\n\t\t\t\t\t\tforeach (var callback in fieldCallbacks.ToList())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tisTriggering = true;\n\t\t\t\t\t\t\t\tcallback.DynamicInvoke(change.Value, change.PreviousValue);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch (Exception e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tColyseusContext.Logger.LogError(e.Message);\n\t\t\t\t\t\t\t} finally\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tisTriggering = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t//\n\t\t\t\t\t// Handle collection of items\n\t\t\t\t\t//\n\t\t\t\t\tISchemaCollection container = (ISchemaCollection)_ref;\n\n\t\t\t\t\tif ((change.Op & (byte)OPERATION.DELETE) == (byte)OPERATION.DELETE)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (change.PreviousValue != container.GetTypeDefaultValue())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// trigger onRemove\n\t\t\t\t\t\t\tcallbacks.TryGetValue(OPERATION.DELETE, out var deleteCallbacks);\n\t\t\t\t\t\t\tif (deleteCallbacks != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tforeach (var callback in deleteCallbacks)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcallback.DynamicInvoke(change.DynamicIndex ?? change.Field, change.PreviousValue);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Handle DELETE_AND_ADD operation\n\t\t\t\t\t\tif ((change.Op & (byte)OPERATION.ADD) == (byte)OPERATION.ADD)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// trigger onRemove\n\t\t\t\t\t\t\tcallbacks.TryGetValue(OPERATION.ADD, out var addCallbacks);\n\t\t\t\t\t\t\tif (addCallbacks != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tisTriggering = true;\n\t\t\t\t\t\t\t\tforeach (var callback in addCallbacks)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcallback.DynamicInvoke(change.DynamicIndex, change.Value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tisTriggering = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\telse if (\n\t\t\t\t\t\t(change.Op & (byte)OPERATION.ADD) == (byte)OPERATION.ADD &&\n\t\t\t\t\t\tchange.PreviousValue != change.Value\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// trigger onAdd\n\t\t\t\t\t\tcallbacks.TryGetValue(OPERATION.ADD, out var addCallbacks);\n\t\t\t\t\t\tif (addCallbacks != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisTriggering = true;\n\t\t\t\t\t\t\tforeach (var callback in addCallbacks)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallback.DynamicInvoke(change.DynamicIndex ?? change.Field, change.Value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tisTriggering = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// trigger onChange\n\t\t\t\t\tif (change.Value != change.PreviousValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tcallbacks.TryGetValue(OPERATION.REPLACE, out var replaceCallbacks);\n\t\t\t\t\t\tif (replaceCallbacks != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var callback in replaceCallbacks)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallback.DynamicInvoke(change.DynamicIndex ?? change.Field, change.Value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tUniqueRefIds.Add(refId);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class Callbacks // <T> where T : Schema\n\t{\n\t\tpublic static StateCallbackStrategy<T> Get<T>(Room<T> room)\n\t\t\twhere T : Schema\n\t\t{\n\t\t\tvar decoder = (room.Serializer as SchemaSerializer<T>).Decoder;\n\t\t\treturn new StateCallbackStrategy<T>(decoder);\n\t\t}\n\n\t\tpublic static StateCallbackStrategy<T> Get<T>(Decoder<T> decoder)\n\t\t\twhere T : Schema\n\t\t{\n\t\t\treturn new StateCallbackStrategy<T>(decoder);\n\t\t}\n\n\t\tinternal static void RemoveChildRefs(ISchemaCollection collection, List<DataChange> changes, ReferenceTracker refs)\n\t\t{\n\t\t\tif (refs == null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcollection.ForEach((key, value) => {\n\t\t\t\tchanges.Add(new DataChange\n\t\t\t\t{\n\t\t\t\t\tRefId = collection.__refId,\n\t\t\t\t\tOp = (byte)OPERATION.DELETE,\n\t\t\t\t\t//Field = item.Key,\n\t\t\t\t\tDynamicIndex = key,\n\t\t\t\t\tValue = null,\n\t\t\t\t\tPreviousValue = value\n\t\t\t\t});\n\n\t\t\t\tif (collection.HasSchemaChild)\n\t\t\t\t{\n\t\t\t\t\trefs.Remove((value as IRef).__refId);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Callbacks/Callbacks.cs.meta",
    "content": "fileFormatVersion: 2\nguid: cdc421113be204ebf86bc7061decb2a5"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Callbacks.meta",
    "content": "fileFormatVersion: 2\nguid: 20021fffe9f50415790a724749f52d37\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Decoder.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Colyseus.Schema\n{\n    public delegate void TriggerChangesDelegate(ref List<DataChange> changes);\n\n    public class Decoder<T> where T : Schema\n    {\n        public ReferenceTracker Refs = new ReferenceTracker();\n        public TypeContext Context = new TypeContext();\n        public T State;\n\n        public TriggerChangesDelegate TriggerChanges;\n\t\tprotected List<DataChange> AllChanges = new List<DataChange>();\n\n\t\t/// <summary>\n\t\t///     DynamicTypeDefinitions keyed by typeId, populated during Handshake when T is DynamicSchema.\n\t\t/// </summary>\n\t\tinternal Dictionary<float, DynamicTypeDefinition> DynamicDefinitions;\n\n\t\t/// <summary>\n\t\t///     Maps collection refIds to their child element typeId (for DynamicSchema support).\n\t\t/// </summary>\n\t\tprivate Dictionary<int, float> _collectionChildTypeId;\n\n\t\tpublic Decoder()\n\t\t{\n            State = Activator.CreateInstance<T>();\n            Refs.Add(0, State);\n        }\n\n\t\t/// <summary>\n\t\t///     Decode incoming data\n\t\t/// </summary>\n\t\t/// <param name=\"bytes\">The incoming data</param>\n\t\t/// <param name=\"it\"><see cref=\"Iterator\" /> used to  If null, will create a new one</param>\n\t\t/// <param name=\"refs\">\n\t\t///     <see cref=\"ReferenceTracker\" /> for all refs found through the decoding process. If null, will\n\t\t///     create a new one\n\t\t/// </param>\n\t\t/// <exception cref=\"Exception\">If no decoding fails</exception>\n\t\tpublic void Decode(byte[] bytes, Iterator it = null)\n\t\t{\n\t\t\tif (it == null)\n\t\t\t{\n\t\t\t\tit = new Iterator();\n\t\t\t}\n\n\t\t\tint refId = 0;\n\t\t\tIRef _ref = State;\n\n\t\t\tAllChanges.Clear();\n\n\t\t\tint totalBytes = bytes.Length;\n\n\t\t\twhile (it.Offset < totalBytes)\n\t\t\t{\n\t\t\t\tif (bytes[it.Offset] == (byte)SPEC.SWITCH_TO_STRUCTURE)\n\t\t\t\t{\n\t\t\t\t\tit.Offset++;\n\n\t\t\t\t\trefId = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\n\t\t\t\t\tif (_ref is IArraySchema) { ((IArraySchema)_ref).OnDecodeEnd(); }\n\n\t\t\t\t\t_ref = Refs.Get(refId);\n\n\t\t\t\t\t//\n\t\t\t\t\t// Trying to access a reference that haven't been decoded yet.\n\t\t\t\t\t//\n\t\t\t\t\tif (_ref == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new Exception(\"refId not found: \" + refId);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tbool isSchemaDefinitionMismatch;\n\n\t\t\t\tif (_ref is Schema)\n\t\t\t\t{\n\t\t\t\t\tisSchemaDefinitionMismatch = !DecodeSchema(bytes, it, (Schema)_ref);\n\t\t\t\t}\n\t\t\t\telse if (_ref is IMapSchema)\n\t\t\t\t{\n\t\t\t\t\tisSchemaDefinitionMismatch = !DecodeMapSchema(bytes, it, (IMapSchema)_ref);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tisSchemaDefinitionMismatch = !DecodeArraySchema(bytes, it, (IArraySchema)_ref);\n\t\t\t\t}\n\n\t\t\t\tif (isSchemaDefinitionMismatch)\n\t\t\t\t{\n\t\t\t\t\t//\n\t\t\t\t\t// keep skipping next bytes until reaches a known structure\n\t\t\t\t\t// by local decoder.\n\t\t\t\t\t//\n\t\t\t\t\tIterator nextIterator = new Iterator { Offset = it.Offset };\n\n\t\t\t\t\twhile (it.Offset < totalBytes)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (Utils.Decode.SwitchStructureCheck(bytes, it))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnextIterator.Offset = it.Offset + 1;\n\t\t\t\t\t\t\tif (Refs.Has(Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, nextIterator))))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tit.Offset++;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (_ref is IArraySchema) { ((IArraySchema)_ref).OnDecodeEnd(); }\n\n\t\t\tTriggerChanges?.Invoke(ref AllChanges);\n\n\t\t\tRefs.GarbageCollection();\n\t\t}\n\n\t\tprotected void DecodeValue(byte[] bytes, Iterator it, IRef _ref, int fieldIndex, string fieldType, System.Type childType, byte operation, out object value, out object previousValue)\n\t\t{\n\t\t\tpreviousValue = _ref.GetByIndex(fieldIndex);\n\n\t\t\t//\n\t\t\t// Delete operations\n\t\t\t//\n\t\t\tif ((operation & (byte)OPERATION.DELETE) == (byte)OPERATION.DELETE)\n\t\t\t{\n\t\t\t\t// Flag `refId` for garbage collection.\n\t\t\t\tif (previousValue != null && previousValue is IRef)\n\t\t\t\t{\n\t\t\t\t\tRefs.Remove(((IRef)previousValue).__refId);\n\t\t\t\t}\n\n\t\t\t\tif (operation != (byte)OPERATION.DELETE_AND_ADD)\n\t\t\t\t{\n\t\t\t\t\t_ref.DeleteByIndex(fieldIndex);\n\t\t\t\t}\n\n\t\t\t\tvalue = null;\n\t\t\t}\n\n\t\t\tif (operation == (byte)OPERATION.DELETE)\n\t\t\t{\n\t\t\t\t//\n\t\t\t\t// FIXME: refactor me.\n\t\t\t\t// Don't do anything.\n\t\t\t\t//\n\t\t\t\tvalue = null;\n\n\t\t\t}\n\t\t\telse if (fieldType == \"ref\")\n\t\t\t{\n\t\t\t\tvar __refId = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\t\t\t\tvalue = Refs.Get(__refId);\n\n\t\t\t\tif ((operation & (byte)OPERATION.ADD) == (byte)OPERATION.ADD)\n\t\t\t\t{\n\t\t\t\t\tfloat resolvedTypeId;\n\t\t\t\t\tSystem.Type concreteChildType = GetSchemaType(bytes, it, childType, out resolvedTypeId);\n\t\t\t\t\tif (value == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = CreateTypeInstance(concreteChildType);\n\t\t\t\t\t\t((IRef)value).__refId = __refId;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Assign DynamicTypeDefinition for DynamicSchema instances\n\t\t\t\t\tif (DynamicDefinitions != null && value is DynamicSchema dynamicValue && dynamicValue.Definition == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (resolvedTypeId < 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// No TYPE_ID in stream, determine from parent context\n\t\t\t\t\t\t\tif (_ref is DynamicSchema parentDs &&\n\t\t\t\t\t\t\t\tparentDs.Definition != null &&\n\t\t\t\t\t\t\t\tparentDs.Definition.FieldsByIndex.TryGetValue(fieldIndex, out var fn) &&\n\t\t\t\t\t\t\t\tparentDs.Definition.FieldReferencedTypes.TryGetValue(fn, out var parentTypeId))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tresolvedTypeId = parentTypeId;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (_ref is ISchemaCollection &&\n\t\t\t\t\t\t\t\t_collectionChildTypeId != null &&\n\t\t\t\t\t\t\t\t_collectionChildTypeId.TryGetValue(_ref.__refId, out var colTypeId))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tresolvedTypeId = colTypeId;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (resolvedTypeId >= 0 && DynamicDefinitions.TryGetValue(resolvedTypeId, out var def))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdynamicValue.Definition = def;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tRefs.Add(__refId, (IRef)value, (\n\t\t\t\t\t\tvalue != previousValue ||  // increment ref count if value has changed\n\t\t\t\t\t\t(operation == (byte)OPERATION.DELETE_AND_ADD && value == previousValue) // increment ref count if the same instance is being added again\n\t\t\t\t\t));\n\t\t\t\t}\n\n\t\t\t}\n\t\t\telse if (childType == null)\n\t\t\t{\n\t\t\t\t// primitive values\n\t\t\t\tvalue = Utils.Decode.DecodePrimitiveType(fieldType, bytes, it);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar __refId = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\n\t\t\t\tISchemaCollection valueRef = Refs.Has(__refId)\n\t\t\t\t\t? (ISchemaCollection)previousValue ?? (ISchemaCollection)Refs.Get(__refId)\n\t\t\t\t\t: (ISchemaCollection)Activator.CreateInstance(childType);\n\n\t\t\t\tvalue = valueRef.Clone();\n\t\t\t\t((ISchemaCollection)value).__refId = __refId;\n\n\t\t\t\t// keep reference to nested childPrimitiveType.\n\t\t\t\tstring childPrimitiveType;\n\t\t\t\t((Schema)_ref).fieldsByIndex.TryGetValue(fieldIndex, out var fieldName);\n\t\t\t\t((Schema)_ref).fieldChildPrimitiveTypes.TryGetValue(fieldName, out childPrimitiveType);\n\t\t\t\t((ISchemaCollection)value).ChildPrimitiveType = childPrimitiveType;\n\n\t\t\t\t// Track child typeId for DynamicSchema collections\n\t\t\t\tif (DynamicDefinitions != null && _ref is DynamicSchema parentDs2 &&\n\t\t\t\t\tparentDs2.Definition != null && fieldName != null &&\n\t\t\t\t\tparentDs2.Definition.FieldReferencedTypes.TryGetValue(fieldName, out var collChildTypeId))\n\t\t\t\t{\n\t\t\t\t\tif (_collectionChildTypeId == null) _collectionChildTypeId = new Dictionary<int, float>();\n\t\t\t\t\t_collectionChildTypeId[__refId] = collChildTypeId;\n\t\t\t\t}\n\n\t\t\t\tif (previousValue != null)\n\t\t\t\t{\n\t\t\t\t\tif (\n\t\t\t\t\t\t((IRef)previousValue).__refId > 0 &&\n\t\t\t\t\t\t__refId != ((IRef)previousValue).__refId\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t((ISchemaCollection)previousValue).ForEach((key, value) => {\n\t\t\t\t\t\t\tif (value is IRef) {\n\t\t\t\t\t\t\t\tRefs.Remove(((IRef)value).__refId);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tAllChanges.Add(new DataChange\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tRefId = __refId,\n\t\t\t\t\t\t\t\tDynamicIndex = key,\n\t\t\t\t\t\t\t\tOp = (byte)OPERATION.DELETE,\n\t\t\t\t\t\t\t\tValue = null,\n\t\t\t\t\t\t\t\tPreviousValue = value\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tRefs.Add(__refId, (IRef)value, (\n\t\t\t\t\tvalueRef != previousValue || // increment ref count if value has changed\n\t\t\t\t\t(operation == (byte)OPERATION.DELETE_AND_ADD && valueRef == previousValue) // increment ref count if the same instance is being added again\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tprotected bool DecodeSchema(byte[] bytes, Iterator it, Schema refSchema)\n\t\t{\n\t\t\tbyte firstByte = bytes[it.Offset++];\n\t\t\tbyte operation = (byte) ((firstByte >> 6) << 6); // \"compressed\" index + operation\n\n\t\t\tint fieldIndex = firstByte % (operation == 0 ? 255 : operation); // FIXME: JS allows (0 || 255);\n\n\t\t\trefSchema.fieldsByIndex.TryGetValue(fieldIndex, out var fieldName);\n\t\t\trefSchema.fieldTypes.TryGetValue(fieldName ?? \"\", out var fieldType);\n\t\t\trefSchema.fieldChildTypes.TryGetValue(fieldName ?? \"\", out var childType);\n\n\t\t\tif (fieldName == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tDecodeValue(\n\t\t\t\tbytes,\n\t\t\t\tit,\n\t\t\t\trefSchema,\n\t\t\t\tfieldIndex,\n\t\t\t\tfieldType,\n\t\t\t\tchildType,\n\t\t\t\toperation,\n\t\t\t\tout var value,\n\t\t\t\tout var previousValue\n\t\t\t);\n\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\trefSchema[fieldName] = value;\n\t\t\t}\n\n\t\t\tif (previousValue != value)\n\t\t\t{\n\t\t\t\tAllChanges.Add(new DataChange\n\t\t\t\t{\n\t\t\t\t\tRefId = refSchema.__refId,\n\t\t\t\t\tOp = operation,\n\t\t\t\t\tField = fieldName,\n\t\t\t\t\tValue = value,\n\t\t\t\t\tPreviousValue = previousValue\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected bool DecodeMapSchema (byte[] bytes, Iterator it, IMapSchema refMap)\n\t\t{\n\t\t\tbyte operation = bytes[it.Offset++];\n\n\t\t\tif (operation == (byte)OPERATION.CLEAR)\n\t\t\t{\n\t\t\t\trefMap.Clear(AllChanges, Refs);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tint fieldIndex = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\t\t\tstring fieldType;\n\t\t\tSystem.Type childType = null;\n\n\t\t\tif (refMap.HasSchemaChild)\n\t\t\t{\n\t\t\t\tfieldType = \"ref\";\n\t\t\t\tchildType = refMap.GetChildType();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfieldType = refMap.ChildPrimitiveType;\n\t\t\t}\n\n\t\t\tstring dynamicIndex;\n\n\t\t\tif ((operation & (byte)OPERATION.ADD) == (byte)OPERATION.ADD)\n\t\t\t{\n\t\t\t\t// MapSchema dynamic index.\n\t\t\t\tdynamicIndex = Utils.Decode.DecodeString(bytes, it);\n\t\t\t\trefMap.SetIndex(fieldIndex, dynamicIndex);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdynamicIndex = (string)refMap.GetIndex(fieldIndex);\n\t\t\t}\n\n\t\t\tDecodeValue(\n\t\t\t\tbytes,\n\t\t\t\tit,\n\t\t\t\trefMap,\n\t\t\t\tfieldIndex,\n\t\t\t\tfieldType,\n\t\t\t\tchildType,\n\t\t\t\toperation,\n\t\t\t\tout var value,\n\t\t\t\tout var previousValue\n\t\t\t);\n\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\trefMap.SetByIndex(fieldIndex, dynamicIndex, value);\n\t\t\t}\n\n\t\t\tif (previousValue != value)\n\t\t\t{\n\t\t\t\tAllChanges.Add(new DataChange\n\t\t\t\t{\n\t\t\t\t\tRefId = refMap.__refId,\n\t\t\t\t\tOp = operation,\n\t\t\t\t\tField = null,\n\t\t\t\t\tDynamicIndex = dynamicIndex,\n\t\t\t\t\tValue = value,\n\t\t\t\t\tPreviousValue = previousValue\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected bool DecodeArraySchema(byte[] bytes, Iterator it, IArraySchema refArray)\n\t\t{\n\t\t\tbyte operation = bytes[it.Offset++];\n\t\t\tint index;\n\n\t\t\tif (operation == (byte)OPERATION.CLEAR)\n\t\t\t{\n\t\t\t\trefArray.Clear(AllChanges, Refs);\n\t\t\t\treturn true;\n\n\t\t\t}\n\t\t\telse if (operation == (byte)OPERATION.REVERSE)\n\t\t\t{\n\t\t\t\trefArray.Reverse();\n\t\t\t\treturn true;\n\n\t\t\t}\n\t\t\telse if (operation == (byte)OPERATION.DELETE_BY_REFID)\n\t\t\t{\n\t\t\t\t// TODO: refactor here, try to follow same flow as below\n\t\t\t\tint refId = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\t\t\t\tobject itemByRefId = Refs.Get(refId);\n\t\t\t\tint i = 0;\n\t\t\t\tindex = -1;\n\t\t\t\tforeach (var item in refArray.GetItems())\n\t\t\t\t{\n\t\t\t\t\tif (item == itemByRefId)\n\t\t\t\t\t{\n\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\trefArray.DeleteByIndex(index);\n\t\t\t\tAllChanges.Add(new DataChange\n\t\t\t\t{\n\t\t\t\t\tRefId = refArray.__refId,\n\t\t\t\t\tOp = (byte) OPERATION.DELETE,\n\t\t\t\t\tField = \"\",\n\t\t\t\t\tDynamicIndex = index,\n\t\t\t\t\tValue = null,\n\t\t\t\t\tPreviousValue = itemByRefId\n\t\t\t\t});\n\t\t\t\treturn true;\n\n\t\t\t}\n\t\t\telse if (operation == (byte)OPERATION.ADD_BY_REFID)\n\t\t\t{\n\t\t\t\tint refId = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\t\t\t\tIRef itemByRefId = Refs.Get(refId);\n\n\t\t\t\tindex = -1;\n\t\t\t\tif (itemByRefId != null)\n\t\t\t\t{\n\t\t\t\t\tint i = 0;\n\t\t\t\t\tforeach (var item in refArray.GetItems())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (item == itemByRefId)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (index == -1)\n\t\t\t\t{\n\t\t\t\t\tindex = refArray.Count;\n\t\t\t\t}\n\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tindex = Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n\t\t\t}\n\n\t\t\tstring fieldType;\n\t\t\tSystem.Type childType = null;\n\n\t\t\tif (refArray.HasSchemaChild)\n\t\t\t{\n\t\t\t\tfieldType = \"ref\";\n\t\t\t\tchildType = refArray.GetChildType();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfieldType = refArray.ChildPrimitiveType;\n\t\t\t}\n\n\t\t\tDecodeValue(\n\t\t\t\tbytes,\n\t\t\t\tit,\n\t\t\t\trefArray,\n\t\t\t\tindex,\n\t\t\t\tfieldType,\n\t\t\t\tchildType,\n\t\t\t\toperation,\n\t\t\t\tout var value,\n\t\t\t\tout var previousValue\n\t\t\t);\n\n\t\t\tif (value != null && value != previousValue)\n\t\t\t{\n\t\t\t\trefArray.SetByIndex(index, value, operation);\n\t\t\t}\n\n\t\t\tif (previousValue != value)\n\t\t\t{\n\t\t\t\tAllChanges.Add(new DataChange\n\t\t\t\t{\n\t\t\t\t\tRefId = refArray.__refId,\n\t\t\t\t\tOp = operation,\n\t\t\t\t\tField = null,\n\t\t\t\t\tDynamicIndex = index,\n\t\t\t\t\tValue = value,\n\t\t\t\t\tPreviousValue = previousValue\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Determine what type of <see cref=\"Schema\" /> this is\n\t\t/// </summary>\n\t\t/// <param name=\"bytes\">Incoming data</param>\n\t\t/// <param name=\"it\">\n\t\t///     The <see cref=\"Iterator\" /> used to <see cref=\"Decoder.DecodeNumber\" /> the <paramref name=\"bytes\" />\n\t\t/// </param>\n\t\t/// <param name=\"defaultType\">\n\t\t///     The default <see cref=\"Schema\" /> type, if one cant be determined from the\n\t\t///     <paramref name=\"bytes\" />\n\t\t/// </param>\n\t\t/// <returns>The parsed <see cref=\"System.Type\" /> if found, <paramref name=\"defaultType\" /> if not</returns>\n\t\tprotected System.Type GetSchemaType(byte[] bytes, Iterator it, System.Type defaultType, out float resolvedTypeId)\n        {\n            System.Type type = defaultType;\n            resolvedTypeId = -1;\n\n            if (it.Offset < bytes.Length && bytes[it.Offset] == (byte)SPEC.TYPE_ID)\n            {\n                it.Offset++;\n                resolvedTypeId = (float)Convert.ToInt32(Utils.Decode.DecodeNumber(bytes, it));\n                type = Context.Get(resolvedTypeId);\n            }\n\n            return type;\n        }\n\n        /// <summary>\n        ///     Create an instance of the provided <paramref name=\"type\" />\n        /// </summary>\n        /// <param name=\"type\">The <see cref=\"System.Type\" /> to create an instance of</param>\n        /// <returns></returns>\n        protected object CreateTypeInstance(System.Type type)\n        {\n            return Activator.CreateInstance(type);\n        }\n\n        internal void Teardown()\n\t\t{\n            Refs.Clear();\n        }\n\n\t}\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Decoder.cs.meta",
    "content": "fileFormatVersion: 2\nguid: bf9ddf343365d470598eca60f7ccbeb0\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/DynamicSchema.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Colyseus.Schema\n{\n\t/// <summary>\n\t///     Per-type metadata built from server handshake Reflection data.\n\t///     Analogous to a generated Schema subclass's [Type] attributes,\n\t///     but constructed at runtime.\n\t/// </summary>\n\tpublic class DynamicTypeDefinition\n\t{\n\t\tpublic float TypeId;\n\t\tpublic Dictionary<int, string> FieldsByIndex = new Dictionary<int, string>();\n\t\tpublic Dictionary<string, string> FieldTypes = new Dictionary<string, string>();\n\t\tpublic Dictionary<string, System.Type> FieldChildTypes = new Dictionary<string, System.Type>();\n\t\tpublic Dictionary<string, string> FieldChildPrimitiveTypes = new Dictionary<string, string>();\n\t\tpublic Dictionary<string, float> FieldReferencedTypes = new Dictionary<string, float>();\n\n\t\t/// <summary>\n\t\t///     Parses a ReflectionField into the appropriate dictionaries.\n\t\t/// </summary>\n\t\t/// <param name=\"fieldIndex\">The field index from the reflection data</param>\n\t\t/// <param name=\"fieldName\">The field name</param>\n\t\t/// <param name=\"fieldType\">The field type string (e.g. \"ref\", \"map\", \"array\", \"string\", \"int32\")</param>\n\t\t/// <param name=\"referencedType\">The referenced type id, or -1 for primitives</param>\n\t\tpublic void ParseFieldType(int fieldIndex, string fieldName, string fieldType, float referencedType)\n\t\t{\n\t\t\tFieldsByIndex[fieldIndex] = fieldName;\n\n\t\t\tif (referencedType >= 0)\n\t\t\t{\n\t\t\t\tFieldReferencedTypes[fieldName] = referencedType;\n\t\t\t}\n\n\t\t\tif (fieldType == \"ref\")\n\t\t\t{\n\t\t\t\tFieldTypes[fieldName] = \"ref\";\n\t\t\t\tif (referencedType >= 0)\n\t\t\t\t{\n\t\t\t\t\tFieldChildTypes[fieldName] = typeof(DynamicSchema);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (fieldType == \"map\")\n\t\t\t{\n\t\t\t\tFieldTypes[fieldName] = \"map\";\n\t\t\t\tif (referencedType >= 0)\n\t\t\t\t{\n\t\t\t\t\tFieldChildTypes[fieldName] = typeof(MapSchema<DynamicSchema>);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (fieldType == \"array\")\n\t\t\t{\n\t\t\t\tFieldTypes[fieldName] = \"array\";\n\t\t\t\tif (referencedType >= 0)\n\t\t\t\t{\n\t\t\t\t\tFieldChildTypes[fieldName] = typeof(ArraySchema<DynamicSchema>);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (fieldType.Contains(\":\"))\n\t\t\t{\n\t\t\t\t// Collection of primitives: \"map:string\", \"array:number\", etc.\n\t\t\t\tvar parts = fieldType.Split(':');\n\t\t\t\tvar collectionType = parts[0];\n\t\t\t\tvar primitiveType = parts[1];\n\n\t\t\t\tFieldTypes[fieldName] = collectionType;\n\t\t\t\tFieldChildPrimitiveTypes[fieldName] = primitiveType;\n\n\t\t\t\tif (collectionType == \"map\")\n\t\t\t\t{\n\t\t\t\t\tFieldChildTypes[fieldName] = typeof(MapSchema<object>);\n\t\t\t\t}\n\t\t\t\telse if (collectionType == \"array\")\n\t\t\t\t{\n\t\t\t\t\tFieldChildTypes[fieldName] = typeof(ArraySchema<object>);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Primitive types: \"string\", \"int32\", \"float32\", \"number\", \"boolean\", etc.\n\t\t\t\tFieldTypes[fieldName] = fieldType;\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t///     A Schema subclass that stores values in a dictionary rather than\n\t///     requiring compile-time generated fields. Use with Room&lt;DynamicSchema&gt;\n\t///     to skip code generation entirely.\n\t/// </summary>\n\tpublic class DynamicSchema : Schema\n\t{\n\t\tinternal DynamicTypeDefinition Definition;\n\n\t\tprivate Dictionary<string, object> _values = new Dictionary<string, object>();\n\n\t\t/// <summary>\n\t\t///     Parameterless constructor required for Activator.CreateInstance\n\t\t/// </summary>\n\t\tpublic DynamicSchema() { }\n\n\t\tpublic override object this[string propertyName]\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\t_values.TryGetValue(propertyName, out var value);\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\tset\n\t\t\t{\n\t\t\t\t_values[propertyName] = value;\n\t\t\t}\n\t\t}\n\n\t\tinternal override Dictionary<int, string> fieldsByIndex =>\n\t\t\tDefinition?.FieldsByIndex ?? _emptyFieldsByIndex;\n\n\t\tinternal override Dictionary<string, string> fieldTypes =>\n\t\t\tDefinition?.FieldTypes ?? _emptyFieldTypes;\n\n\t\tinternal override Dictionary<string, System.Type> fieldChildTypes =>\n\t\t\tDefinition?.FieldChildTypes ?? _emptyFieldChildTypes;\n\n\t\tinternal override Dictionary<string, string> fieldChildPrimitiveTypes =>\n\t\t\tDefinition?.FieldChildPrimitiveTypes ?? _emptyFieldChildPrimitiveTypes;\n\n\t\t/// <summary>\n\t\t///     Typed convenience accessor for field values.\n\t\t/// </summary>\n\t\tpublic T Get<T>(string fieldName)\n\t\t{\n\t\t\t_values.TryGetValue(fieldName, out var value);\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\treturn default(T);\n\t\t\t}\n\t\t\tif (value is T typedValue)\n\t\t\t{\n\t\t\t\treturn typedValue;\n\t\t\t}\n\t\t\treturn (T)Convert.ChangeType(value, typeof(T));\n\t\t}\n\n\t\t// Shared empty dictionaries to avoid allocations when Definition is null\n\t\tprivate static readonly Dictionary<int, string> _emptyFieldsByIndex = new Dictionary<int, string>();\n\t\tprivate static readonly Dictionary<string, string> _emptyFieldTypes = new Dictionary<string, string>();\n\t\tprivate static readonly Dictionary<string, System.Type> _emptyFieldChildTypes = new Dictionary<string, System.Type>();\n\t\tprivate static readonly Dictionary<string, string> _emptyFieldChildPrimitiveTypes = new Dictionary<string, string>();\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/DynamicSchema.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 0c5bf7be5839b48abb887366463f49e5"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/ReferenceTracker.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Colyseus.Schema\n{\n    /// <summary>\n    ///     Keep track of and maintain multiple <see cref=\"IRef\" /> objects\n    /// </summary>\n    public class ReferenceTracker\n    {\n        /// <summary>\n        ///     Local list of <see cref=\"IRef\" />s we have scheduled for removal in the next\n        ///     <see cref=\"GarbageCollection\" />\n        /// </summary>\n        public List<int> deletedRefs = new List<int>();\n\n        /// <summary>\n        ///     Map of how many <see cref=\"IRef\" />s we're currently tracking for each ID\n        /// </summary>\n        public Dictionary<int, int> refCounts = new Dictionary<int, int>();\n\n        /// <summary>\n        ///     Map of <see cref=\"IRef\" />s we're tracking\n        /// </summary>\n        public Dictionary<int, IRef> refs = new Dictionary<int, IRef>();\n\n        /// <summary>\n        ///     List of callbacks by refId\n        /// </summary>\n\t\tpublic Dictionary<int, Dictionary<object, List<Delegate>>> callbacks = new Dictionary<int, Dictionary<object, List<Delegate>>>();\n\n        /// <summary>\n        ///     Add a new reference to be tracked\n        /// </summary>\n        /// <param name=\"refId\">The ID of the reference</param>\n        /// <param name=\"_ref\">The object we're tracking</param>\n        /// <param name=\"incrementCount\">If true, we increment the <see cref=\"refCounts\" /> at this ID</param>\n        public void Add(int refId, IRef _ref, bool incrementCount = true)\n        {\n\t\t\trefs[refId] = _ref;\n\n            if (incrementCount)\n            {\n\t\t\t\tint previousCount = (!refCounts.ContainsKey(refId))\n\t\t\t\t\t? 0\n\t\t\t\t\t: refCounts[refId];\n\n\t\t\t\trefCounts[refId] = previousCount + 1;\n            }\n\n\t\t\tif (deletedRefs.Contains(refId)) {\n\t\t\t\tdeletedRefs.Remove(refId);\n\t\t\t}\n\t\t}\n\n        /// <summary>\n        ///     Get a reference by it's ID\n        /// </summary>\n        /// <param name=\"refId\">The ID of the reference requested</param>\n        /// <returns>The reference with that <paramref name=\"refId\" /> in <see cref=\"refs\" />, if it exists</returns>\n        public IRef Get(int refId)\n        {\n            refs.TryGetValue(refId, out var _ref);\n\n            return _ref;\n        }\n\n        /// <summary>\n        ///     Check if <see cref=\"refs\" /> contains <paramref name=\"refId\" />\n        /// </summary>\n        /// <param name=\"refId\">The ID to check for</param>\n        /// <returns>True if <see cref=\"refs\" /> contains <paramref name=\"refId\" />, false otherwise</returns>\n        public bool Has(int refId)\n        {\n            return refs.ContainsKey(refId);\n        }\n\n        /// <summary>\n        ///     Remove a reference by ID\n        /// </summary>\n        /// <param name=\"refId\">The ID of the reference to remove</param>\n        public bool Remove(int refId)\n        {\n            if (!refCounts.ContainsKey(refId))\n            {\n                ColyseusContext.Logger.Log(\"trying to remove refId that doesn't exist: \" + refId);\n                return false;\n            }\n\n            refCounts[refId] = refCounts[refId] - 1;\n\n            if (refCounts[refId] <= 0)\n            {\n                deletedRefs.Add(refId);\n                return true;\n            }\n\n            return false;\n        }\n\n        /// <summary>\n        ///     Remove all references contained in <see cref=\"deletedRefs\"></see> from the tracking maps (<see cref=\"refs\" /> and\n        ///     <see cref=\"refCounts\" />). Clears <see cref=\"deletedRefs\" /> afterwards\n        /// </summary>\n        public void GarbageCollection()\n        {\n            int totalDeletedRefs = deletedRefs.Count;\n            for (int i = 0; i < totalDeletedRefs; i++)\n            {\n                int refId = deletedRefs[i];\n\n                if (refCounts[refId] <= 0)\n                {\n                    IRef _ref = refs[refId];\n                    if (_ref is Schema)\n                    {\n                        foreach (KeyValuePair<string, System.Type> field in ((Schema)_ref).GetFieldChildTypes())\n                        {\n                            object fieldValue = ((Schema)_ref)[field.Key];\n                            if (fieldValue is IRef)\n                            {\n                                int childRefId = ((IRef)fieldValue).__refId;\n                                if (!deletedRefs.Contains(childRefId) && Remove(childRefId))\n                                {\n                                    totalDeletedRefs++;\n                                }\n                            }\n                        }\n                    }\n                    else if (_ref is ISchemaCollection && ((ISchemaCollection)_ref).HasSchemaChild)\n                    {\n                        ((ISchemaCollection)_ref).ForEach((key, value) =>\n                        {\n                            int childRefId = ((IRef)value).__refId;\n                            if (!deletedRefs.Contains(childRefId) && Remove(childRefId))\n                            {\n                                totalDeletedRefs++;\n                            }\n                        });\n                    }\n\n                    refs.Remove(refId);\n                    refCounts.Remove(refId);\n                    callbacks.Remove(refId);\n                }\n            }\n\n            deletedRefs.Clear();\n        }\n\n        /// <summary>\n        ///     Clear all maps and lists in this tracker\n        /// </summary>\n        public void Clear()\n        {\n            refs.Clear();\n            refCounts.Clear();\n            callbacks.Clear();\n            deletedRefs.Clear();\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/ReferenceTracker.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8d1f13b23a23742dda739d463a4568e2\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Schema.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\n\n// ReSharper disable InconsistentNaming\n\n/***\n  //Allowed primitive types:\n  //  \"string\"\n  //  \"number\"\n  //  \"boolean\"\n  //  \"int8\"\n  //  \"uint8\"\n  //  \"int16\"\n  //  \"uint16\"\n  //  \"int32\"\n  //  \"uint32\"\n  //  \"int64\"\n  //  \"uint64\"\n  //  \"float32\"\n  //  \"float64\"\n\n  //Allowed reference types:\n  //  \"ref\"\n  //  \"array\"\n  //  \"map\"\n***/\n\nnamespace Colyseus.Schema\n{\n\t/// <summary>\n\t///     <see cref=\"Schema\" /> <see cref=\"Attribute\" /> wrapper class\n\t///     <para>Allowed primitive types:</para>\n\t///     <para>\n\t///         <em>\n\t///             \"string\", \"number\", \"boolean\", \"int8\", \"uint8\", \"int16\", \"uint16\", \"int32\", \"uint32\", \"int64\", \"uint64\",\n\t///             \"float32\", \"float64\"\n\t///         </em>\n\t///     </para>\n\t///     <para>Allowed reference types:</para>\n\t///     <para>\n\t///         <em>\"ref\", \"array\", \"map\"</em>\n\t///     </para>\n\t/// </summary>\n\t[AttributeUsage(AttributeTargets.Field)]\n\tpublic class Type : Attribute\n\t{\n\t\t/// <summary>\n\t\t///     The <see cref=\"FieldType\" /> of the <see cref=\"ChildType\" />\n\t\t/// </summary>\n\t\tpublic string ChildPrimitiveType;\n\n\t\t/// <summary>\n\t\t///     What type of <see cref=\"Schema\" /> this attribute is (can be null)\n\t\t/// </summary>\n\t\tpublic System.Type ChildType;\n\n\t\t/// <summary>\n\t\t///     The field type this <see cref=\"Attribute\" /> represents\n\t\t/// </summary>\n\t\tpublic string FieldType;\n\n\t\t/// <summary>\n\t\t///     The index of where this will be stored in the <see cref=\"Schema\" />\n\t\t/// </summary>\n\t\tpublic int Index;\n\n\t\tpublic Type(int index, string type, System.Type childType = null, string childPrimitiveType = null)\n\t\t{\n\t\t\tIndex = index; // GetType().GetFields() doesn't guarantee order of fields, need to manually track them here!\n\t\t\tFieldType = type;\n\t\t\tChildType = childType;\n\t\t\tChildPrimitiveType = childPrimitiveType;\n\t\t}\n\t}\n\n\t/// <summary>\n\t///     Wrapper class containing an <see cref=\"int\" /> offset value\n\t/// </summary>\n\tpublic class Iterator\n\t{\n\t\t/// <summary>\n\t\t///     The value used to offset when we encode/decode data\n\t\t/// </summary>\n\t\tpublic int Offset;\n\t}\n\n\t/// <summary>\n\t///     Byte flags used to signal specific operations to be performed on <see cref=\"Schema\" /> data\n\t/// </summary>\n\tpublic enum SPEC : byte\n\t{\n\t\t/// <summary>\n\t\t///     A decode can be done, begin that process\n\t\t/// </summary>\n\t\tSWITCH_TO_STRUCTURE = 255,\n\n\t\t/// <summary>\n\t\t///     The following bytes will indicate the <see cref=\"Schema\" /> type\n\t\t/// </summary>\n\t\tTYPE_ID = 213\n\t}\n\n\t/// <summary>\n\t///     Byte flags for <see cref=\"DataChange\" /> operations that can be done\n\t/// </summary>\n\t[SuppressMessage(\"ReSharper\", \"MissingXmlDoc\")]\n\tpublic enum OPERATION : byte\n\t{\n\t\tADD = 128,\n\t\tREPLACE = 0,\n\t\tDELETE = 64,\n\t\tDELETE_AND_MOVE = 96, // ArraySchema\n\t\tDELETE_AND_ADD = 192,\n\t\tCLEAR = 10,\n\n\t\t/**\n\t\t * ArraySchema operations\n\t\t */\n\t\tREVERSE = 15,\n\t\tDELETE_BY_REFID = 33,\n\t\tADD_BY_REFID = 129,\n\t}\n\n\t/// <summary>\n\t///     Wrapper class for a <see cref=\"Schema\" /> change\n\t/// </summary>\n\tpublic class DataChange\n\t{\n\t\t/// <summary>\n\t\t///     The reference id of the data change\n\t\t/// </summary>\n\t\tpublic int RefId;\n\n\t\t/// <summary>\n\t\t///     The field index of the data change\n\t\t/// </summary>\n\t\tpublic object DynamicIndex;\n\n\t\t/// <summary>\n\t\t///     The field name of the data\n\t\t/// </summary>\n\t\tpublic string Field;\n\n\t\t/// <summary>\n\t\t///     An <see cref=\"OPERATION\" /> flag for this DataChange\n\t\t/// </summary>\n\t\tpublic byte Op;\n\n\t\t/// <summary>\n\t\t///     The value of the old data\n\t\t/// </summary>\n\t\tpublic object PreviousValue;\n\n\t\t/// <summary>\n\t\t///     The value of the new data\n\t\t/// </summary>\n\t\tpublic object Value;\n\t}\n\n\t/// <summary>\n\t///     Interface for a collection of multiple <see cref=\"Schema\" />s\n\t/// </summary>\n\t[SuppressMessage(\"ReSharper\", \"MissingXmlDoc\")]\n\tpublic interface ISchemaCollection : IRef\n\t{\n\t\tbool HasSchemaChild { get; }\n\t\tstring ChildPrimitiveType { get; set; }\n\n\t\tint Count { get; }\n\t\tobject this[object key] { get; set; }\n\n\t\tIEnumerable GetItems();\n\t\tvoid ForEach(Action<object, object> action);\n\t\tvoid SetItems(object items);\n\t\tvoid Clear(List<DataChange> changes, ReferenceTracker refs);\n\n\t\tSystem.Type GetChildType();\n\t\tobject GetTypeDefaultValue();\n\n\t\tISchemaCollection Clone();\n\t}\n\n\t[SuppressMessage(\"ReSharper\", \"MissingXmlDoc\")]\n\tpublic interface IArraySchema : ISchemaCollection\n\t{\n\t\tvoid OnDecodeEnd();\n\t\tvoid SetByIndex(int index, object value, byte operation);\n\t\tvoid Reverse();\n\t}\n\n\t[SuppressMessage(\"ReSharper\", \"MissingXmlDoc\")]\n\tpublic interface IMapSchema : ISchemaCollection\n\t{\n\t\tvoid SetIndex(int index, object dynamicIndex);\n\t\tobject GetIndex(int index);\n\t\tvoid SetByIndex(int index, object dynamicIndex, object value);\n\t}\n\n\t/// <summary>\n\t///     Interface for an object that can be tracked by a <see cref=\"ReferenceTracker\" />\n\t/// </summary>\n\t[SuppressMessage(\"ReSharper\", \"MissingXmlDoc\")]\n\tpublic interface IRef\n\t{\n\t\t/// <summary>\n\t\t///     The ID with which this <see cref=\"IRef\" /> instance will be tracked\n\t\t/// </summary>\n\t\tint __refId { get; set; }\n\n\t\tobject GetByIndex(int index);\n\t\tvoid DeleteByIndex(int index);\n\t}\n\n\t/// <summary>\n\t///     Data structure representing a <see cref=\"Room{T}\" />'s state (synchronizeable data)\n\t/// </summary>\n\tpublic class Schema : IRef\n\t{\n\t\tprivate static readonly Dictionary<System.Type, Metadata> _cachedMetadata = new Dictionary<System.Type, Metadata>();\n\n\t\tprivate readonly Metadata _metadata;\n\n\t\t/// <summary>\n\t\t///     Map of the <see cref=\"Type.ChildPrimitiveType\" />s that this schema uses\n\t\t/// </summary>\n\t\tinternal virtual Dictionary<string, string> fieldChildPrimitiveTypes => _metadata.FieldChildPrimitiveTypes;\n\n\t\t/// <summary>\n\t\t///     Map of the <see cref=\"Type.ChildType\" />s that this schema uses\n\t\t/// </summary>\n\t\tinternal virtual Dictionary<string, System.Type> fieldChildTypes => _metadata.FieldChildTypes;\n\n\t\t/// <summary>\n\t\t///     Map of the fields in this schema using {<see cref=\"Type.Index\" />,\n\t\t/// </summary>\n\t\tinternal virtual Dictionary<int, string> fieldsByIndex => _metadata.FieldsByIndex;\n\n\t\t/// <summary>\n\t\t///     Map of the field types in this schema\n\t\t/// </summary>\n\t\tinternal virtual Dictionary<string, string> fieldTypes => _metadata.FieldTypes;\n\n\t\tpublic Schema()\n\t\t{\n\t\t\tvar type = GetType();\n\t\t\tif (!_cachedMetadata.TryGetValue(type, out _metadata))\n\t\t\t{\n\t\t\t\t_metadata = CreateMetadata(type);\n\t\t\t\t_cachedMetadata.Add(type, _metadata);\n\t\t\t}\n\t\t}\n\n\n\t\tprivate static Metadata CreateMetadata(System.Type type)\n\t\t{\n\t\t\tvar metadata = new Metadata();\n\n\t\t\tFieldInfo[] fields = type.GetFields();\n\t\t\tforeach (FieldInfo field in fields)\n\t\t\t{\n\t\t\t\tobject[] typeAttributes = field.GetCustomAttributes(typeof(Type), true);\n\t\t\t\tfor (int i = 0; i < typeAttributes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tType t = (Type)typeAttributes[i];\n\t\t\t\t\tmetadata.FieldsByIndex.Add(t.Index, field.Name);\n\t\t\t\t\tmetadata.FieldTypes.Add(field.Name, t.FieldType);\n\n\t\t\t\t\tif (t.ChildPrimitiveType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tmetadata.FieldChildPrimitiveTypes.Add(field.Name, t.ChildPrimitiveType);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (t.ChildType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tmetadata.FieldChildTypes.Add(field.Name, t.ChildType);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn metadata;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Allow get and set of property values by its <paramref name=\"propertyName\" />\n\t\t/// </summary>\n\t\t/// <param name=\"propertyName\">The object's field name</param>\n\t\tpublic virtual object this[string propertyName]\n\t\t{\n\t\t\tget { return GetType().GetField(propertyName).GetValue(this); }\n\t\t\tset\n\t\t\t{\n\t\t\t\tFieldInfo field = GetType().GetField(propertyName);\n\t\t\t\tfield.SetValue(this, value);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     <see cref=\"IRef\" /> implementation - ID with which to reference this <see cref=\"Schema\" />\n\t\t/// </summary>\n\t\tpublic int __refId { get; set; }\n\n\t\t/// <summary>\n\t\t///     Get a field by it's index\n\t\t/// </summary>\n\t\t/// <param name=\"index\">Index of the field to get</param>\n\t\t/// <returns>The <see cref=\"object\" /> at that index (if it exists)</returns>\n\t\tpublic object GetByIndex(int index)\n\t\t{\n\t\t\tfieldsByIndex.TryGetValue(index, out var fieldName);\n\t\t\treturn this[fieldName];\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Remove the field by it's index\n\t\t/// </summary>\n\t\t/// <param name=\"index\">Index of the field to remove</param>\n\t\tpublic void DeleteByIndex(int index)\n\t\t{\n\t\t\tfieldsByIndex.TryGetValue(index, out var fieldName);\n\t\t\tthis[fieldName] = null;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Getter function, required for <see cref=\"ReferenceTracker.GarbageCollection\" />\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t///     <see cref=\"fieldChildTypes\" />\n\t\t/// </returns>\n\t\tinternal Dictionary<string, System.Type> GetFieldChildTypes()\n\t\t{\n\t\t\t// This is required for \"garbage collection\" inside ReferenceTracker.\n\t\t\treturn fieldChildTypes;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Check if this <see cref=\"Schema\" /> has a <see cref=\"Schema\" /> child\n\t\t/// </summary>\n\t\t/// <param name=\"toCheck\"><see cref=\"Schema\" /> type to check for</param>\n\t\t/// <returns>True if found, false otherwise</returns>\n\t\tpublic static bool CheckSchemaChild(System.Type toCheck)\n\t\t{\n\t\t\tSystem.Type generic = typeof(Schema);\n\n\t\t\twhile (toCheck != null && toCheck != typeof(object))\n\t\t\t{\n\t\t\t\tSystem.Type cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;\n\n\t\t\t\tif (generic == cur)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\ttoCheck = toCheck.BaseType;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t///\t\tMetadata for Schema type\n\t\t/// </summary>\n\t\tprivate class Metadata\n\t\t{\n\t\t\t/// <summary>\n\t\t\t///     Map of the <see cref=\"Type.ChildPrimitiveType\" />s that this schema uses\n\t\t\t/// </summary>\n\t\t\tpublic Dictionary<string, string> FieldChildPrimitiveTypes = new Dictionary<string, string>();\n\n\t\t\t/// <summary>\n\t\t\t///     Map of the <see cref=\"Type.ChildType\" />s that this schema uses\n\t\t\t/// </summary>\n\t\t\tpublic Dictionary<string, System.Type> FieldChildTypes = new Dictionary<string, System.Type>();\n\n\t\t\t/// <summary>\n\t\t\t///     Map of the fields in this schema using {<see cref=\"Type.Index\" />,\n\t\t\t/// </summary>\n\t\t\tpublic Dictionary<int, string> FieldsByIndex = new Dictionary<int, string>();\n\n\t\t\t/// <summary>\n\t\t\t///     Map of the field types in this schema\n\t\t\t/// </summary>\n\t\t\tpublic Dictionary<string, string> FieldTypes = new Dictionary<string, string>();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Schema.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 7e50bf707193ce547b13afb98abb3b48\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/TypeContext.cs",
    "content": "using System.Collections.Generic;\n\nnamespace Colyseus.Schema\n{\n    /// <summary>\n    ///     Internal container class for tracking and maintaining the context of the current application\n    /// </summary>\n    public class TypeContext\n    {\n        /// <summary>\n        ///     Schema types and IDs we're aware of\n        /// </summary>\n        protected Dictionary<float, System.Type> typeIds = new Dictionary<float, System.Type>();\n\n        protected List<System.Type> types = new List<System.Type>(); //TODO: This does not appear to be used ever\n\n        /// <summary>\n        ///     Add a new Schema type by id\n        /// </summary>\n        /// <param name=\"type\">The incoming schema type</param>\n        /// <param name=\"typeid\">The schema type ID we received via server Handshake</param>\n        public void SetTypeId(System.Type type, float typeid)\n        {\n            typeIds[typeid] = type;\n        }\n\n        /// <summary>\n        ///     Get the <see cref=\"System.Type\" /> with a given <paramref name=\"typeid\" />\n        /// </summary>\n        /// <param name=\"typeid\">The schema type ID</param>\n        /// <returns>The schema type we previous have set with <see cref=\"SetTypeId\" /></returns>\n        public System.Type Get(float typeid)\n        {\n            return typeIds[typeid]; //TODO: Confirm if this can ever fail and if so we should handle it gracefully\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/TypeContext.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a1b0877a82fcf4867af631924169de16"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/ArraySchema.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing Colyseus;\n\nnamespace Colyseus.Schema\n{\n\t/// <summary>\n\t///     A <see cref=\"Schema\" /> array of <typeparamref name=\"T\" /> type objects\n\t/// </summary>\n\t/// <typeparam name=\"T\">The type of object in this array</typeparam>\n\tpublic class ArraySchema<T> : IArraySchema\n\t{\n\t\t/// <summary>\n\t\t///     The contents of the <see cref=\"ArraySchema{T}\" />\n\t\t/// </summary>\n\t\tpublic List<T> items;\n\n\t\tinternal HashSet<int> deletedKeys = new HashSet<int>();\n\n\t\t[Preserve]\n\t\tpublic ArraySchema()\n\t\t{\n\t\t\titems = new List<T>();\n\t\t}\n\n\t\tpublic ArraySchema(List<T> items = null)\n\t\t{\n\t\t\tthis.items = items ?? new List<T>();\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Accessor to get/set <see cref=\"items\" /> by index\n\t\t/// </summary>\n\t\tpublic T this[int index]\n\t\t{\n\t\t\tget { return items[index]; }\n\t\t\tset { items[index] = value; }\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic int __refId { get; set; }\n\n\t\tpublic void SetByIndex(int index, object value, byte operation)\n\t\t{\n\t\t\tdeletedKeys.Remove(index);\n\n\t\t\tif (\n\t\t\t\tindex == 0 &&\n\t\t\t\toperation == (byte)OPERATION.ADD &&\n\t\t\t\titems.Count > 0\n\t\t\t)\n\t\t\t{\n\t\t\t\t// handle decoding unshift\n\t\t\t\titems.Insert(0, (T)value);\n\t\t\t}\n\t\t\telse if (operation == (byte)OPERATION.DELETE_AND_MOVE)\n\t\t\t{\n\t\t\t\titems.RemoveAt(index);\n\n\t\t\t\tfor (int i = items.Count; i <= index; i++)\n\t\t\t\t{\n\t\t\t\t\titems.Add(default(T));\n\t\t\t\t}\n\n\t\t\t\titems[index] = (T)value;\n\t\t\t\t// items.Insert(index, (T) value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (int i = items.Count; i <= index; i++)\n\t\t\t\t{\n\t\t\t\t\titems.Add(default(T));\n\t\t\t\t}\n\n\t\t\t\titems[index] = (T)value;\n\t\t\t\t// items.Insert(index, (T) value);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Get an item out of the <see cref=\"ArraySchema{T}\" /> by it's index\n\t\t/// </summary>\n\t\t/// <param name=\"index\">The index of the item</param>\n\t\t/// <returns>An object of type <typeparamref name=\"T\" /> if it exists</returns>\n\t\tpublic object GetByIndex(int index)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn items[index];\n\t\t\t}\n\t\t\tcatch (ArgumentOutOfRangeException)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Remove an item and it's dynamic index reference\n\t\t/// </summary>\n\t\t/// <param name=\"index\">The index of the item</param>\n\t\tpublic void DeleteByIndex(int index)\n\t\t{\n\t\t\tdeletedKeys.Add(index);\n\n\t\t\t// skip if index is out of range\n\t\t\tif (index >= items.Count)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titems[index] = default(T);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Clear all items and indices\n\t\t/// </summary>\n\t\t/// <param name=\"refs\">Passed in for garbage collection, if needed</param>\n\t\tpublic void Clear(List<DataChange> changes, ReferenceTracker refs)\n\t\t{\n\t\t\tCallbacks.RemoveChildRefs(this, changes, refs);\n\t\t\titems.Clear();\n\t\t}\n\n\t\tpublic void Reverse()\n\t\t{\n\t\t\titems.Reverse();\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Clone this <see cref=\"ArraySchema{T}\" />\n\t\t/// </summary>\n\t\t/// <returns>A copy of this <see cref=\"ArraySchema{T}\" /></returns>\n\t\tpublic ISchemaCollection Clone()\n\t\t{\n\t\t\tArraySchema<T> clone = new ArraySchema<T>(items);\n\t\t\treturn clone;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Determine what type of item this <see cref=\"ArraySchema{T}\" /> contains\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t///     <code>typeof(<typeparamref name=\"T\" />);</code>\n\t\t/// </returns>\n\t\tpublic System.Type GetChildType()\n\t\t{\n\t\t\treturn typeof(T);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Get the default value of <typeparamref name=\"T\" />\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t///     <code>default(<typeparamref name=\"T\" />);</code>\n\t\t/// </returns>\n\t\tpublic object GetTypeDefaultValue()\n\t\t{\n\t\t\treturn default(T);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Getter for <see cref=\"HasSchemaChild\" />\n\t\t///     <para>This calls: <code>Schema.CheckSchemaChild(typeof(T))</code></para>\n\t\t/// </summary>\n\t\tpublic bool HasSchemaChild { get; } = Schema.CheckSchemaChild(typeof(T));\n\n\t\t/// <summary>\n\t\t///     Getter/Setter of the <see cref=\"Type.ChildPrimitiveType\" /> that this <see cref=\"ArraySchema{T}\" />\n\t\t///     contains\n\t\t/// </summary>\n\t\tpublic string ChildPrimitiveType { get; set; }\n\n\t\t/// <summary>\n\t\t///     Getter for the amount of <see cref=\"items\" /> in this <see cref=\"ArraySchema{T}\" />\n\t\t/// </summary>\n\t\tpublic int Count\n\t\t{\n\t\t\tget { return items.Count; }\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Accessor to get/set <see cref=\"items\" /> with a <paramref name=\"key\" />\n\t\t/// </summary>\n\t\t/// <param name=\"key\"></param>\n\t\tpublic object this[object key]\n\t\t{\n\t\t\tget { return this[(int)key]; }\n\t\t\tset { items[(int)key] = HasSchemaChild ? (T)value : (T)Convert.ChangeType(value, typeof(T)); }\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Getter function to get all the <see cref=\"items\" /> in this <see cref=\"ArraySchema{T}\" />\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t///     <see cref=\"items\" />\n\t\t/// </returns>\n\t\tpublic IEnumerable GetItems()\n\t\t{\n\t\t\treturn items;\n\t\t}\n\n\t\tpublic int IndexOf(T value)\n\t\t{\n\t\t\tint i = 0;\n\t\t\tforeach (var item in items)\n\t\t\t{\n\t\t\t\tif (item.Equals(value))\n\t\t\t\t{\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Setter function to cast and set <see cref=\"items\" />\n\t\t/// </summary>\n\t\t/// <param name=\"items\">\n\t\t///     The items to pass to the <see cref=\"ArraySchema{T}\" />. Will be cast to Dictionary{int,\n\t\t///     <typeparamref name=\"T\" />}\n\t\t/// </param>\n\t\tpublic void SetItems(object items)\n\t\t{\n\t\t\tthis.items = (List<T>)items;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Function to iterate over <see cref=\"items\" /> and perform an <see cref=\"Action{T}\" /> upon each entry\n\t\t/// </summary>\n\t\t/// <param name=\"action\">The <see cref=\"Action\" /> to perform</param>\n\t\tpublic void ForEach(Action<int, T> action)\n\t\t{\n\t\t\tint i = 0;\n\t\t\titems.ForEach((value) =>\n\t\t\t{\n\t\t\t\taction(i, value);\n\t\t\t\ti++;\n\t\t\t});\n\t\t}\n\n\t\tpublic void ForEach(Action<object, object> action)\n\t\t{\n\t\t\tint i = 0;\n\t\t\titems.ForEach((value) =>\n\t\t\t{\n\t\t\t\taction(i, value);\n\t\t\t\ti++;\n\t\t\t});\n\t\t}\n\n\t\tpublic void OnDecodeEnd()\n\t\t{\n\t\t\tif (deletedKeys.Count == 0)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar newItems = new List<T>();\n\n\t\t\tfor (int i = 0; i < items.Count; i++)\n\t\t\t{\n\t\t\t\tif (deletedKeys.Contains(i))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tnewItems.Add(items[i]);\n\t\t\t}\n\n\t\t\titems = newItems;\n\n\t\t\tdeletedKeys.Clear();\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/ArraySchema.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3ab256d5bbbf81a4591a87d62c22a878\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/CustomType.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Colyseus.Schema\n{\n\tclass CustomType\n\t{\n\t\tprotected static CustomType instance = new CustomType();\n\t\tprotected Dictionary<string, System.Type> types = new Dictionary<string, System.Type>();\n\t\t//{\n\t\t//\t\t[\"array\"] = ArraySchema\n\t\t//};\n\n\t\tpublic static CustomType GetInstance()\n\t\t{\n\t\t\treturn instance;\n\t\t}\n\n\t\tpublic void Add(string id, System.Type type)\n\t\t{\n\t\t\tif (!types.ContainsKey(id))\n\t\t\t{\n\t\t\t\ttypes.Add(id, type);\n\t\t\t}\n\t\t}\n\n\t\tpublic System.Type Get(string id)\n\t\t{\n\t\t\tSystem.Type type;\n\t\t\ttypes.TryGetValue(id, out type);\n\t\t\treturn type;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/CustomType.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8797edbee9b8f41e0ad98a6c35a02c43\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/MapSchema.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\n\nnamespace Colyseus.Schema\n{\n    /// <summary>\n    ///     A <see cref=\"Schema\" /> dictionary of <typeparamref name=\"T\" /> type objects\n    /// </summary>\n    /// <typeparam name=\"T\">The type of object in this map</typeparam>\n    public class MapSchema<T> : IMapSchema\n    {\n        protected Dictionary<int, string> Indexes = new Dictionary<int, string>();\n\n        /// <summary>\n        ///     The contents of the <see cref=\"MapSchema{T}\" />\n        /// </summary>\n        public OrderedDictionary items = new OrderedDictionary();\n\n        [Preserve]\n        public MapSchema()\n        {\n            items = new OrderedDictionary();\n        }\n\n        public MapSchema(OrderedDictionary items = null)\n        {\n            this.items = items ?? new OrderedDictionary();\n        }\n\n        /// <summary>\n        ///     Accessor to get/set <see cref=\"items\" /> with a <paramref name=\"key\" />\n        /// </summary>\n        /// <param name=\"key\"></param>\n        public T this[string key]\n        {\n            get\n            {\n                T value;\n                TryGetValue(key, out value);\n                return value;\n            }\n            set { items[key] = value; }\n        }\n\n        /// <summary>\n        ///     Getter for all of the keys in <see cref=\"items\" />\n        /// </summary>\n        public ICollection Keys\n        {\n            get { return items.Keys; }\n        }\n\n        /// <summary>\n        ///     Getter for all of the values in <see cref=\"items\" />\n        /// </summary>\n        public ICollection Values\n        {\n            get { return items.Values; }\n        }\n\n        public int __refId { get; set; }\n\n        /// <summary>\n        ///     Set the <see cref=\"indexes\" /> value\n        /// </summary>\n        /// <param name=\"index\">The field index</param>\n        /// <param name=\"dynamicIndex\">The new dynamic Index value, cast to <see cref=\"int\" /></param>\n        public void SetIndex(int index, object dynamicIndex)\n        {\n            Indexes[index] = (string) dynamicIndex;\n        }\n\n        /// <summary>\n        ///     Set an Item by it's <paramref name=\"dynamicIndex\" />\n        /// </summary>\n        /// <param name=\"index\">\n        ///     Sets <see cref=\"Indexes\" /> value at <paramref name=\"index\" /> to <paramref name=\"dynamicIndex\" />\n        /// </param>\n        /// <param name=\"dynamicIndex\">\n        ///     The index, cast to <see cref=\"string\" />, in <see cref=\"items\" /> that will be set to <paramref name=\"value\" />\n        /// </param>\n        /// <param name=\"value\">The new object to put into <see cref=\"items\" /></param>\n        public void SetByIndex(int index, object dynamicIndex, object value)\n        {\n            Indexes[index] = (string) dynamicIndex;\n            items[dynamicIndex] = (T) value;\n        }\n\n        /// <summary>\n        ///     Get the dynamic index value from <see cref=\"Indexes\" />\n        /// </summary>\n        /// <param name=\"index\">The location of the dynamic index to return</param>\n        /// <returns>The dynamic index from <see cref=\"Indexes\" />, if it exists. <see cref=\"string.Empty\" /> if it does not</returns>\n        public object GetIndex(int index)\n        {\n            string dynamicIndex;\n\n            Indexes.TryGetValue(index, out dynamicIndex);\n\n            return dynamicIndex;\n        }\n\n        /// <summary>\n        ///     Get an item out of the <see cref=\"MapSchema{T}\" /> by it's index\n        /// </summary>\n        /// <param name=\"index\">The index of the item</param>\n        /// <returns>An object of type <typeparamref name=\"T\" /> if it exists</returns>\n        public object GetByIndex(int index)\n        {\n            string dynamicIndex = (string) GetIndex(index);\n            return dynamicIndex != null && items.Contains(dynamicIndex)\n                ? items[dynamicIndex]\n                : GetTypeDefaultValue();\n        }\n\n        /// <summary>\n        ///     Remove an item and it's dynamic index reference\n        /// </summary>\n        /// <param name=\"index\">The index of the item</param>\n        public void DeleteByIndex(int index)\n        {\n            string dynamicIndex = (string) GetIndex(index);\n            if (\n                //\n                // FIXME:\n                // The schema encoder should not encode a DELETE operation when using ADD + DELETE in the same key. (in the same patch)\n                //\n                dynamicIndex != null &&\n                items.Contains(dynamicIndex)\n            )\n            {\n                items.Remove(dynamicIndex);\n                Indexes.Remove(index);\n            }\n        }\n\n        /// <summary>\n        ///     Clone this <see cref=\"MapSchema{T}\" />\n        /// </summary>\n        /// <returns>A copy of this <see cref=\"MapSchema{T}\" /></returns>\n        public ISchemaCollection Clone()\n        {\n            MapSchema<T> clone = new MapSchema<T>(items)\n            {\n                Indexes = Indexes\n            };\n            return clone;\n        }\n\n        /// <summary>\n        ///     Determine what type of item this <see cref=\"MapSchema{T}\" /> contains\n        /// </summary>\n        /// <returns>\n        ///     <code>typeof(<typeparamref name=\"T\" />);</code>\n        /// </returns>\n        public System.Type GetChildType()\n        {\n            return typeof(T);\n        }\n\n        /// <summary>\n        ///     Get the default value of <typeparamref name=\"T\" />\n        /// </summary>\n        /// <returns>\n        ///     <code>default(<typeparamref name=\"T\" />);</code>\n        /// </returns>\n        public object GetTypeDefaultValue()\n        {\n            return default(T);\n        }\n\n        /// <summary>\n        ///     Determine if this <see cref=\"MapSchema{T}\" /> contains <paramref name=\"key\" />\n        /// </summary>\n        /// <param name=\"key\">The key in <see cref=\"items\" /> that will be checked for</param>\n        /// <returns>True if <see cref=\"items\" /> contains the <paramref name=\"key\" />, false if not</returns>\n        public bool ContainsKey(object key)\n        {\n            return items.Contains(key);\n        }\n\n        /// <summary>\n        ///     Getter for <see cref=\"HasSchemaChild\" />\n        ///     <para>This calls: <code>Schema.CheckSchemaChild(typeof(T))</code></para>\n        /// </summary>\n        public bool HasSchemaChild { get; } = Schema.CheckSchemaChild(typeof(T));\n\n        /// <summary>\n        ///     Getter/Setter of the <see cref=\"Type.ChildPrimitiveType\" /> that this <see cref=\"MapSchema{T}\" />\n        ///     contains\n        /// </summary>\n        public string ChildPrimitiveType { get; set; }\n\n        /// <summary>\n        ///     Accessor to get/set <see cref=\"items\" /> with a <paramref name=\"key\" />\n        /// </summary>\n        /// <param name=\"key\"></param>\n        public object this[object key]\n        {\n            get { return this[(string) key]; }\n            set { items[(string) key] = HasSchemaChild ? (T) value : (T) Convert.ChangeType(value, typeof(T)); }\n        }\n\n        /// <summary>\n        ///     Getter function to get all the <see cref=\"items\" /> in this <see cref=\"MapSchema{T}\" />\n        /// </summary>\n        /// <returns>\n        ///     <see cref=\"items\" />\n        /// </returns>\n        public IEnumerable GetItems()\n        {\n            return items;\n        }\n\n        /// <summary>\n        ///     Clear all items and indices\n        /// </summary>\n        /// <param name=\"refs\">Passed in for garbage collection, if needed</param>\n        public void Clear(List<DataChange> changes, ReferenceTracker refs)\n        {\n\t\t\tCallbacks.RemoveChildRefs(this, changes, refs);\n\t\t\tIndexes.Clear();\n            items.Clear();\n        }\n\n\t\tpublic void Reverse()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n        /// <summary>\n        ///     Getter for the amount of <see cref=\"items\" /> in this <see cref=\"MapSchema{T}\" />\n        /// </summary>\n        public int Count\n        {\n            get { return items.Count; }\n        }\n\n        /// <summary>\n        ///     <b>UNIMPLEMENTED</b> setter function to set <see cref=\"items\" />\n        /// </summary>\n        /// <param name=\"items\">\n        ///     The items to pass to the <see cref=\"MapSchema{T}\" />\n        /// </param>\n        public void SetItems(object items) //TODO: Is it ok if this is unimplemented?\n        {\n            throw new NotImplementedException();\n        }\n\n        /// <summary>\n        ///     Add a new item into <see cref=\"items\" />\n        /// </summary>\n        /// <param name=\"item\">The new entry for <see cref=\"items\" /></param>\n        public void Add(KeyValuePair<string, T> item)\n        {\n            items[item.Key] = item.Value;\n        }\n\n        /// <summary>\n        ///     Check if an <paramref name=\"item\" /> exists in <see cref=\"items\" />\n        /// </summary>\n        /// <param name=\"item\">The value to check for</param>\n        /// <returns>True if <paramref name=\"item\" /> is found in <see cref=\"items\" />, false otherwise</returns>\n        public bool Contains(KeyValuePair<string, T> item)\n        {\n            return items.Contains(item.Key);\n        }\n\n        /// <summary>\n        ///     Remove an item from this <see cref=\"MapSchema{T}\" />'s <see cref=\"items\" />\n        /// </summary>\n        /// <param name=\"item\">The item to remove</param>\n        /// <returns>\n        ///     True if <paramref name=\"item\" /> was found and removed, false if it was not in the <see cref=\"items\" /> to\n        ///     begin with\n        /// </returns>\n        public bool Remove(KeyValuePair<string, T> item)\n        {\n            T value;\n            if (TryGetValue(item.Key, out value) && Equals(value, item.Value))\n            {\n                Remove(item.Key);\n                return true;\n            }\n\n            return false;\n        }\n\n        /// <summary>\n        ///     Add a new item to <see cref=\"items\" />\n        /// </summary>\n        /// <param name=\"key\">The field name</param>\n        /// <param name=\"value\">The data to add</param>\n        public void Add(string key, T value)\n        {\n            items.Add(key, value);\n        }\n\n        public bool Remove(string key)\n        {\n            bool result = items.Contains(key);\n            if (result)\n            {\n                items.Remove(key);\n            }\n\n            return result;\n        }\n\n        public bool TryGetValue(string key, out T value)\n        {\n            object foundValue;\n            if ((foundValue = items[key]) != null || items.Contains(key))\n            {\n                // Either found with a non-null value, or contained value is null.\n                value = (T) foundValue;\n                return true;\n            }\n\n            value = default;\n            return false;\n        }\n\n        /// <summary>\n        ///     Function to iterate over <see cref=\"items\" /> and perform an <see cref=\"Action{T}\" /> upon each entry\n        /// </summary>\n        /// <param name=\"action\">The <see cref=\"Action\" /> to perform</param>\n        public void ForEach(Action<string, T> action)\n        {\n            foreach (DictionaryEntry item in items)\n            {\n                action((string) item.Key, (T) item.Value);\n            }\n        }\n\n        public void ForEach(Action<object, object> action)\n        {\n            foreach (DictionaryEntry item in items)\n            {\n                action(item.Key, item.Value);\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/MapSchema.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ef32bb4c29e82a54d8c9ae61fbba9b56\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/Reflection.cs",
    "content": "using Colyseus;\n\nnamespace Colyseus.Schema\n{\n    /// <summary>\n    ///     <see cref=\"Schema\" /> used for the purposes of reflection\n    /// </summary>\n    [Preserve]\n    public class ReflectionField : Schema\n    {\n        /// <summary>\n        ///     The field name\n        /// </summary>\n        [Type(0, \"string\")]\n        public string name;\n\n        /// <summary>\n        ///     The type of the field\n        /// </summary>\n        [Type(1, \"string\")]\n        public string type;\n\n        [Type(2, \"number\")]\n        public float referencedType = -1;\n    }\n\n    /// <summary>\n    ///     Mid level reflection container of an <see cref=\"ArraySchema{T}\" />\n    /// </summary>\n    [Preserve]\n    public class ReflectionType : Schema\n    {\n        /// <summary>\n        ///     The ID of this <see cref=\"Schema\" />\n        /// </summary>\n        [Type(0, \"number\")]\n        public float id;\n\n        /// <summary>\n        ///     The ID of which structure this <see cref=\"Schema\" /> extends\n        /// </summary>\n        [Type(1, \"number\")]\n        public float extendsId = -1;\n\n        /// <summary>\n        ///     An <see cref=\"ArraySchema{T}\" /> of <see cref=\"ReflectionField\" />\n        /// </summary>\n        [Preserve]\n        [Type(2, \"array\", typeof(ArraySchema<ReflectionField>))]\n        public ArraySchema<ReflectionField> fields;\n\n        [Preserve]\n        public ReflectionType() {}\n    }\n\n    /// <summary>\n    ///     Top level reflection container for an <see cref=\"ArraySchema{T}\" />\n    /// </summary>\n    [Preserve]\n    public class Reflection : Schema\n    {\n        /// <summary>\n        ///     An <see cref=\"ArraySchema{T}\" /> of <see cref=\"ReflectionType\" />\n        /// </summary>\n        [Preserve]\n        [Type(0, \"array\", typeof(ArraySchema<ReflectionType>))]\n        public ArraySchema<ReflectionType> types;\n\n        [Type(1, \"number\")]\n        public float rootType = -1;\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types/Reflection.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 65dac8d9cc95b40899c31429819d6949\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Types.meta",
    "content": "fileFormatVersion: 2\nguid: 917dd28b10759a045b773955c84601bf\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Utils/Decode.cs",
    "content": "using System;\nusing System.Text;\nusing MiscUtil.Conversion;\n\nnamespace Colyseus.Schema.Utils\n{\n\tpublic class Decode\n\t{\n        public static LittleEndianBitConverter bitConverter = new LittleEndianBitConverter();\n\n        /// <summary>\n        ///     Decodes incoming data into an <see cref=\"object\" /> based off of the <paramref name=\"type\" /> provided\n        /// </summary>\n        /// <param name=\"type\">What type of <see cref=\"object\" /> we expect this data to be.\n        ///     <para>Will determine the Decode method used</para>\n        /// </param>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns>A decoded <see cref=\"object\" /> that has been decoded with a <paramref name=\"type\" /> specified method</returns>\n        public static object DecodePrimitiveType(string type, byte[] bytes, Iterator it)\n        {\n            if (type == \"string\")\n            {\n                return DecodeString(bytes, it);\n            }\n\n            if (type == \"number\")\n            {\n                return DecodeNumber(bytes, it);\n            }\n\n            if (type == \"int8\")\n            {\n                return DecodeInt8(bytes, it);\n            }\n\n            if (type == \"uint8\")\n            {\n                return DecodeUint8(bytes, it);\n            }\n\n            if (type == \"int16\")\n            {\n                return DecodeInt16(bytes, it);\n            }\n\n            if (type == \"uint16\")\n            {\n                return DecodeUint16(bytes, it);\n            }\n\n            if (type == \"int32\")\n            {\n                return DecodeInt32(bytes, it);\n            }\n\n            if (type == \"uint32\")\n            {\n                return DecodeUint32(bytes, it);\n            }\n\n            if (type == \"int64\")\n            {\n                return DecodeInt64(bytes, it);\n            }\n\n            if (type == \"uint64\")\n            {\n                return DecodeUint64(bytes, it);\n            }\n\n            if (type == \"float32\")\n            {\n                return DecodeFloat32(bytes, it);\n            }\n\n            if (type == \"float64\")\n            {\n                return DecodeFloat64(bytes, it);\n            }\n\n            if (type == \"boolean\")\n            {\n                return DecodeBoolean(bytes, it);\n            }\n\n            return null;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a <see cref=\"float\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a <see cref=\"float\" /></returns>\n        public static float DecodeNumber(byte[] bytes, Iterator it)\n        {\n            byte prefix = bytes[it.Offset++];\n\n            if (prefix < 0x80)\n            {\n                // positive fixint\n                return prefix;\n            }\n\n            if (prefix == 0xca)\n            {\n                // float 32\n                return DecodeFloat32(bytes, it);\n            }\n\n            if (prefix == 0xcb)\n            {\n                // float 64\n                return (float)DecodeFloat64(bytes, it);\n            }\n\n            if (prefix == 0xcc)\n            {\n                // uint 8\n                return DecodeUint8(bytes, it);\n            }\n\n            if (prefix == 0xcd)\n            {\n                // uint 16\n                return DecodeUint16(bytes, it);\n            }\n\n            if (prefix == 0xce)\n            {\n                // uint 32\n                return DecodeUint32(bytes, it);\n            }\n\n            if (prefix == 0xcf)\n            {\n                // uint 64\n                return DecodeUint64(bytes, it);\n            }\n\n            if (prefix == 0xd0)\n            {\n                // int 8\n                return DecodeInt8(bytes, it);\n            }\n\n            if (prefix == 0xd1)\n            {\n                // int 16\n                return DecodeInt16(bytes, it);\n            }\n\n            if (prefix == 0xd2)\n            {\n                // int 32\n                return DecodeInt32(bytes, it);\n            }\n\n            if (prefix == 0xd3)\n            {\n                // int 64\n                return DecodeInt64(bytes, it);\n            }\n\n            if (prefix > 0xdf)\n            {\n                // negative fixint\n                return (0xff - prefix + 1) * -1;\n            }\n\n            return float.NaN;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into an 8-bit <see cref=\"int\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into an 8-bit <see cref=\"int\" /></returns>\n        public static sbyte DecodeInt8(byte[] bytes, Iterator it)\n        {\n            return Convert.ToSByte((DecodeUint8(bytes, it) << 24) >> 24);\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into an 8-bit <see cref=\"uint\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into an 8-bit <see cref=\"uint\" /></returns>\n        public static byte DecodeUint8(byte[] bytes, Iterator it)\n        {\n            return bytes[it.Offset++];\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 16-bit <see cref=\"int\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 16-bit <see cref=\"int\" /></returns>\n        public static short DecodeInt16(byte[] bytes, Iterator it)\n        {\n            short value = bitConverter.ToInt16(bytes, it.Offset);\n            it.Offset += 2;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 16-bit <see cref=\"uint\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 16-bit <see cref=\"uint\" /></returns>\n        public static ushort DecodeUint16(byte[] bytes, Iterator it)\n        {\n            ushort value = bitConverter.ToUInt16(bytes, it.Offset);\n            it.Offset += 2;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 32-bit <see cref=\"int\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 32-bit <see cref=\"int\" /></returns>\n        public static int DecodeInt32(byte[] bytes, Iterator it)\n        {\n            int value = bitConverter.ToInt32(bytes, it.Offset);\n            it.Offset += 4;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 32-bit <see cref=\"uint\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 32-bit <see cref=\"uint\" /></returns>\n        public static uint DecodeUint32(byte[] bytes, Iterator it)\n        {\n            uint value = bitConverter.ToUInt32(bytes, it.Offset);\n            it.Offset += 4;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 32-bit <see cref=\"float\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 32-bit <see cref=\"float\" /></returns>\n        public static float DecodeFloat32(byte[] bytes, Iterator it)\n        {\n            float value = bitConverter.ToSingle(bytes, it.Offset);\n            it.Offset += 4;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 64-bit <see cref=\"float\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 64-bit <see cref=\"float\" /></returns>\n        public static double DecodeFloat64(byte[] bytes, Iterator it)\n        {\n            double value = bitConverter.ToDouble(bytes, it.Offset);\n            it.Offset += 8;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 64-bit <see cref=\"int\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 64-bit <see cref=\"int\" /></returns>\n        public static long DecodeInt64(byte[] bytes, Iterator it)\n        {\n            long value = bitConverter.ToInt64(bytes, it.Offset);\n            it.Offset += 8;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a 64-bit <see cref=\"uint\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a 64-bit <see cref=\"uint\" /></returns>\n        public static ulong DecodeUint64(byte[] bytes, Iterator it)\n        {\n            ulong value = bitConverter.ToUInt64(bytes, it.Offset);\n            it.Offset += 8;\n            return value;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a <see cref=\"bool\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a <see cref=\"bool\" /></returns>\n        public static bool DecodeBoolean(byte[] bytes, Iterator it)\n        {\n            return DecodeUint8(bytes, it) > 0;\n        }\n\n        /// <summary>\n        ///     Decode method to decode <paramref name=\"bytes\" /> into a <see cref=\"string\" />\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns><paramref name=\"bytes\" /> decoded into a <see cref=\"string\" /></returns>\n        public static string DecodeString(byte[] bytes, Iterator it)\n        {\n            int prefix = bytes[it.Offset++];\n\n            int length;\n            if (prefix < 0xc0)\n            {\n                // fixstr\n                length = prefix & 0x1f;\n            }\n            else if (prefix == 0xd9)\n            {\n                length = (int)DecodeUint8(bytes, it);\n            }\n            else if (prefix == 0xda)\n            {\n                length = DecodeUint16(bytes, it);\n            }\n            else if (prefix == 0xdb)\n            {\n                length = (int)DecodeUint32(bytes, it);\n            }\n            else\n            {\n                length = 0;\n            }\n\n            string str = Encoding.UTF8.GetString(bytes, it.Offset, length);\n            it.Offset += length;\n\n            return str;\n        }\n\n        /// <summary>\n        ///     Checks if\n        ///     <code>bytes[it.Offset] == (byte)SPEC.SWITCH_TO_STRUCTURE</code>\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns>\n        ///     True if the current <see cref=\"Iterator.Offset\" /> works with this array of <paramref name=\"bytes\" />, false\n        ///     otherwise\n        /// </returns>\n        public static bool SwitchStructureCheck(byte[] bytes, Iterator it)\n        {\n            return bytes[it.Offset] == (byte)SPEC.SWITCH_TO_STRUCTURE;\n        }\n\n        /// <summary>\n        ///     Checks if the incoming <paramref name=\"bytes\" /> is a number\n        /// </summary>\n        /// <param name=\"bytes\">The incoming data</param>\n        /// <param name=\"it\">The iterator who's <see cref=\"Iterator.Offset\" /> will be used to Decode the data</param>\n        /// <returns>True if <paramref name=\"bytes\" /> can be resolved into a number, false otherwise</returns>\n        public static bool NumberCheck(byte[] bytes, Iterator it)\n        {\n            byte prefix = bytes[it.Offset];\n            return prefix < 0x80 || prefix >= 0xca && prefix <= 0xd3;\n        }\n    }\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Utils/Decode.cs.meta",
    "content": "fileFormatVersion: 2\nguid: dd65c771c1d0b44399010708ca01d75d"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Utils/Encode.cs",
    "content": "using System;\n\nnamespace Colyseus.Schema.Utils\n{\n\tpublic class Encode\n\t{\n        /// <summary>\n        ///     Retrieves the initial bytes from <paramref name=\"encodedType\" /> based on it's length\n        /// </summary>\n        /// <param name=\"encodedType\">The incoming \"type\" encoded to a <see cref=\"byte\" />[]</param>\n        /// <returns>The important bytes we need based upon the incoming type</returns>\n        /// <exception cref=\"Exception\"></exception>\n        public static byte[] getInitialBytesFromEncodedType(byte[] encodedType, byte protocol)\n        {\n            byte[] initialBytes = { protocol };\n\n            if (encodedType.Length < 0x20)\n            {\n                initialBytes = addByteToArray(initialBytes, new[] { (byte)(encodedType.Length | 0xa0) });\n            }\n            else if (encodedType.Length < 0x100)\n            {\n                initialBytes = addByteToArray(initialBytes, new byte[] { 0xd9 });\n                initialBytes = uint8(initialBytes, encodedType.Length);\n            }\n            else if (encodedType.Length < 0x10000)\n            {\n                initialBytes = addByteToArray(initialBytes, new byte[] { 0xda });\n                initialBytes = uint16(initialBytes, encodedType.Length);\n            }\n            else if (encodedType.Length < 0x7fffffff)\n            {\n                initialBytes = addByteToArray(initialBytes, new byte[] { 0xdb });\n                initialBytes = uint32(initialBytes, encodedType.Length);\n            }\n            else\n            {\n                throw new Exception(\"String too long\");\n            }\n\n            return initialBytes;\n        }\n\n        private static byte[] addByteToArray(byte[] byteArray, byte[] newBytes)\n        {\n            byte[] bytes = new byte[byteArray.Length + newBytes.Length];\n            Buffer.BlockCopy(byteArray, 0, bytes, 0, byteArray.Length);\n            Buffer.BlockCopy(newBytes, 0, bytes, byteArray.Length, newBytes.Length);\n            return bytes;\n        }\n\n        private static byte[] uint8(byte[] bytes, int value)\n        {\n            return addByteToArray(bytes, new[] { (byte)(value & 255) });\n        }\n\n        private static byte[] uint16(byte[] bytes, int value)\n        {\n            byte[] a1 = addByteToArray(bytes, new[] { (byte)(value & 255) });\n            return addByteToArray(a1, new[] { (byte)((value >> 8) & 255) });\n        }\n\n        private static byte[] uint32(byte[] bytes, int value)\n        {\n            int b4 = value >> 24;\n            int b3 = value >> 16;\n            int b2 = value >> 8;\n            int b1 = value;\n            byte[] a1 = addByteToArray(bytes, new[] { (byte)(b1 & 255) });\n            byte[] a2 = addByteToArray(a1, new[] { (byte)(b2 & 255) });\n            byte[] a3 = addByteToArray(a2, new[] { (byte)(b3 & 255) });\n            return addByteToArray(a3, new[] { (byte)(b4 & 255) });\n        }\n\n    }\n\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Utils/Encode.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8b9a0de6846c54eec8dcc45f10ed3b1c"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema/Utils.meta",
    "content": "fileFormatVersion: 2\nguid: bb2c980af108447b0ae4b3af69848342\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Schema.meta",
    "content": "fileFormatVersion: 2\nguid: 0bddc8a03e686dc43bea0c9ceec6d774\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/SchemaSerializer.cs",
    "content": "using System;\nusing System.Reflection;\nusing System.Collections.Generic;\nusing Colyseus.Schema;\nusing Type = Colyseus.Schema.Type;\n\nnamespace Colyseus\n{\n\t/// <summary>\n\t///     An instance of ISerializer specifically for <see cref=\"Schema\" /> based serialization\n\t/// </summary>\n\t/// <typeparam name=\"T\">A child of <see cref=\"Schema\" /></typeparam>\n\tpublic class SchemaSerializer<T> : ISerializer<T> where T : Schema.Schema\n\t{\n\t\tpublic Decoder<T> Decoder = new Decoder<T>();\n\n\t\t/// <summary>\n\t\t///     A reference to the <see cref=\"Iterator\" />\n\t\t/// </summary>\n\t\tprotected Iterator It = new Iterator();\n\n\t\t/// <inheritdoc />\n\t\tpublic void SetState(byte[] data, int offset = 0)\n\t\t{\n\t\t\tIt.Offset = offset;\n\t\t\tDecoder.Decode(data, It);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic T GetState()\n\t\t{\n\t\t\treturn Decoder.State;\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic void Patch(byte[] data, int offset = 0)\n\t\t{\n\t\t\tIt.Offset = offset;\n\t\t\tDecoder.Decode(data, It);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic void Teardown()\n\t\t{\n\t\t\t// Clear all stored references.\n\t\t\tDecoder.Teardown();\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic void Handshake(byte[] bytes, int offset)\n\t\t{\n\t\t\tIterator it = new Iterator { Offset = offset };\n\n\t\t\tvar reflectionDecoder = new Decoder<Reflection>();\n\t\t\treflectionDecoder.Decode(bytes, it);\n\n\t\t\tvar reflection = reflectionDecoder.State;\n\t\t\tvar types = reflection.types.items.ToArray();\n\n\t\t\tif (typeof(T) == typeof(DynamicSchema))\n\t\t\t{\n\t\t\t\tHandshakeDynamic(reflection, types);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tSystem.Type targetType = typeof(T);\n\n\t\t\tSystem.Type[] allTypes = targetType.Assembly.GetTypes();\n\t\t\tList<System.Type> namespaceSchemaTypes = new List<System.Type>(Array.FindAll(allTypes, t => t.Namespace == targetType.Namespace && typeof(Schema.Schema).IsAssignableFrom( targetType)));\n\n\t\t\tfor (int i = 0; i < reflection.types.Count; i++)\n\t\t\t{\n\t\t\t\tvar reflectionType = reflection.types[i];\n\t\t\t\tvar reflectionFields = GetFieldsFromType(reflectionType, types);\n\n\t\t\t\tvar schemaType = namespaceSchemaTypes.Find(t => CompareTypes(t, reflectionFields));\n\n\t\t\t\tif (schemaType != null)\n\t\t\t\t{\n\t\t\t\t\tDecoder.Context.SetTypeId(schemaType, reflection.types[i].id);\n\n\t\t\t\t\t// Remove from list to avoid duplicate checks\n\t\t\t\t\tnamespaceSchemaTypes.Remove(schemaType);\n\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tColyseusContext.Logger.LogWarning(\n\t\t\t\t\t\t\"Local schema mismatch from server. Use \\\"schema-codegen\\\" to generate up-to-date local definitions.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void HandshakeDynamic(Reflection reflection, ReflectionType[] types)\n\t\t{\n\t\t\tDecoder.DynamicDefinitions = new Dictionary<float, DynamicTypeDefinition>();\n\n\t\t\tfor (int i = 0; i < reflection.types.Count; i++)\n\t\t\t{\n\t\t\t\tvar reflectionType = reflection.types[i];\n\t\t\t\tvar reflectionFields = GetFieldsFromType(reflectionType, types);\n\n\t\t\t\tvar definition = new DynamicTypeDefinition();\n\t\t\t\tdefinition.TypeId = reflectionType.id;\n\n\t\t\t\tfor (int j = 0; j < reflectionFields.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tvar field = reflectionFields[j];\n\t\t\t\t\tdefinition.ParseFieldType(j, field.name, field.type, field.referencedType);\n\t\t\t\t}\n\n\t\t\t\tDecoder.DynamicDefinitions[reflectionType.id] = definition;\n\t\t\t\tDecoder.Context.SetTypeId(typeof(DynamicSchema), reflectionType.id);\n\t\t\t}\n\n\t\t\t// Assign root definition\n\t\t\tvar rootTypeId = reflection.rootType >= 0\n\t\t\t\t? reflection.rootType\n\t\t\t\t: (reflection.types.Count > 0 ? reflection.types[0].id : -1);\n\n\t\t\tif (rootTypeId >= 0)\n\t\t\t{\n\t\t\t\tvar rootState = Decoder.State as DynamicSchema;\n\t\t\t\tif (rootState != null && Decoder.DynamicDefinitions.TryGetValue(rootTypeId, out var rootDef))\n\t\t\t\t{\n\t\t\t\t\trootState.Definition = rootDef;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static string DebugReflectionType(ReflectionType reflectionType, List<ReflectionField> reflectionFields)\n\t\t{\n\t\t\tList<string> fieldNames = new List<string>();\n\t\t\tfor (int i = 0; i < reflectionFields.Count; i++)\n\t\t\t{\n\t\t\t\tfieldNames.Add(reflectionFields[i].name);\n\t\t\t}\n\t\t\treturn $\"TypeId: {reflectionType.id} (extendsId: {reflectionType.extendsId}), Fields: {string.Join(\", \", fieldNames)}\";\n\t\t}\n\n\t\tprivate static bool CompareTypes(System.Type schemaType, List<ReflectionField> reflectionFields)\n\t\t{\n\t\t\tFieldInfo[] fields = schemaType.GetFields();\n\t\t\tint typedFieldCount = 0;\n\n\t\t\tforeach (FieldInfo field in fields)\n\t\t\t{\n\t\t\t\tobject[] typeAttributes = field.GetCustomAttributes(typeof(Type), true);\n\t\t\t\tif (typeAttributes.Length != 1)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tType typedField = (Type)typeAttributes[0];\n\n\t\t\t\t// Skip if reflectionType doesn't have the field\n\t\t\t\tif (typedField.Index >= reflectionFields.Count)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tReflectionField reflectionField = reflectionFields[typedField.Index];\n\n\t\t\t\tif (\n\t\t\t\t\treflectionField.type.IndexOf(typedField.FieldType) != 0 ||\n\t\t\t\t\treflectionField.name != field.Name\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\ttypedFieldCount++;\n\t\t\t}\n\n\t\t\t// skip if number of Type'd fields doesn't match\n\t\t\tif (typedFieldCount != reflectionFields.Count)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate List<ReflectionField> GetFieldsFromType(ReflectionType reflectionType, ReflectionType[] types)\n\t\t{\n\t\t\tvar reflectionFields = new List<ReflectionField>();\n\n\t\t\t// Find all types in the inheritance chain from child to root\n\t\t\tList<ReflectionType> inheritanceChain = new List<ReflectionType>();\n\t\t\tvar extendsId = reflectionType.id;\n\t\t\twhile (extendsId != -1)\n\t\t\t{\n\t\t\t\tvar currentType = Array.Find(types, t => t.id == extendsId);\n\t\t\t\tinheritanceChain.Insert(0, currentType); // Insert at the beginning to reverse order\n\t\t\t\textendsId = currentType.extendsId;\n\t\t\t}\n\n\t\t\t// Collect fields from each type in the chain, from root to child\n\t\t\tforeach (var type in inheritanceChain)\n\t\t\t{\n\t\t\t\ttype.fields.ForEach((_, field) => reflectionFields.Add(field));\n\t\t\t}\n\n\t\t\treturn reflectionFields;\n\t\t}\n\t}\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/SchemaSerializer.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c2a698bbb71fc4545a17aed07000db46\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Serializer.cs",
    "content": "namespace Colyseus\n{\n    /// <summary>\n    ///     Serializer Interface\n    /// </summary>\n    /// <typeparam name=\"T\">The type of state this serializer will be for</typeparam>\n    public interface ISerializer<T>\n    {\n        /// <summary>\n        ///     Set the serializer's state\n        /// </summary>\n        /// <param name=\"data\">The incoming state data</param>\n        /// <param name=\"offset\">Offset for reading the incoming data</param>\n        void SetState(byte[] data, int offset);\n\n        /// <summary>\n        ///     Get the current state\n        /// </summary>\n        /// <returns>An object of type <typeparamref name=\"T\" /> representing the current state</returns>\n        T GetState();\n\n        /// <summary>\n        ///     Apply a patch to this state\n        /// </summary>\n        /// <param name=\"data\">The incoming state data</param>\n        /// <param name=\"offset\">Offset for reading the incoming data</param>\n        void Patch(byte[] data, int offset);\n\n        /// <summary>\n        ///     Clean-up functionality\n        /// </summary>\n        void Teardown();\n\n        /// <summary>\n        ///     Confirms connection and serialization is working properly\n        /// </summary>\n        /// <param name=\"bytes\">The handshake data to serialize</param>\n        /// <param name=\"offset\">Offset for reading the incoming data</param>\n        void Handshake(byte[] bytes, int offset);\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer/Serializer.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 4fcf3a67477874e14b7685c3d289d252\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Serializer.meta",
    "content": "fileFormatVersion: 2\nguid: 6a0c82fa6f9124a47a4f2b068619c7d3\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Settings/Settings.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine;\n#endif\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Contains relevant Colyseus settings\n    /// </summary>\n#if UNITY_5_3_OR_NEWER\n    [CreateAssetMenu(fileName = \"MyServerSettings\", menuName = \"Colyseus/Server Settings Scriptable Object\", order = 1)]\n    [Serializable]\n    public class Settings : ScriptableObject\n#else\n    [Serializable]\n    public class Settings\n#endif\n    {\n        /// <summary>\n        ///     The server address\n        /// </summary>\n        public string colyseusServerAddress = \"localhost\";\n\n        /// <summary>\n        ///     The port to connect to\n        /// </summary>\n        public string colyseusServerPort = \"2567\";\n\n        /// <summary>\n        ///     If true, we use secure protocols (wss, https) otherwise we use ws, http (based on <see cref=\"useWss\"/>)\n        /// </summary>\n        public bool useSecureProtocol = false;\n\n        /// <summary>\n        /// Internal wrapper class for a Request header\n        /// </summary>\n        [Serializable]\n        public class RequestHeader\n        {\n            public string name;\n            public string value;\n        }\n\n#if UNITY_5_3_OR_NEWER\n        [SerializeField]\n#endif\n        private RequestHeader[] _requestHeaders;\n\n        private Dictionary<string, string> _headersDictionary;\n\n        public void SetRequestHeaders(RequestHeader[] headers)\n        {\n            _requestHeaders = new RequestHeader[headers.Length];\n            for (int i = 0; i < headers.Length; i++)\n            {\n                _requestHeaders[i] = headers[i];\n            }\n        }\n\n        public RequestHeader[] GetRequestHeaders()\n        {\n            return _requestHeaders;\n        }\n\n        /// <summary>\n        /// Convert the user-defined <see cref=\"_requestHeaders\"/> into a dictionary\n        /// </summary>\n        public Dictionary<string, string> Headers\n        {\n            get\n            {\n                if (_headersDictionary == null)\n                {\n                    _headersDictionary = new Dictionary<string, string>();\n\n\t\t\t\t\tfor (int i = 0; _requestHeaders != null && i < _requestHeaders.Length; ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\t_headersDictionary.Add(_requestHeaders[i].name, _requestHeaders[i].value);\n\t\t\t\t\t}\n\t\t\t\t}\n\n                return _headersDictionary;\n            }\n        }\n\n        /// <summary>\n        ///     Centralized location to build and return the WebSocketEndpoint\n        /// </summary>\n        public string WebSocketEndpoint\n        {\n            get\n            {\n\t\t\t\treturn BuildWebSocketEndpoint();\n\t\t\t}\n        }\n\n        /// <summary>\n        ///     Centralized location to build and return an WebRequestEndpoint\n        /// </summary>\n        public string WebRequestEndpoint\n        {\n            get\n            {\n\t\t\t\treturn BuildWebRequestEndpoint();\n\t\t\t}\n        }\n\n        public static Settings Create()\n        {\n#if UNITY_5_3_OR_NEWER\n            return CreateInstance<Settings>();\n#else\n            return new Settings();\n#endif\n        }\n\n        /// <summary>\n        /// Create a copy of the provided <see cref=\"Settings\"/> object\n        /// </summary>\n        /// <param name=\"orig\">The settings to copy</param>\n        /// <returns>A new instance of <see cref=\"Settings\"/> with values copied from the provided object</returns>\n        public static Settings Clone(Settings orig)\n        {\n            Settings clone = Create();\n            clone.colyseusServerAddress = orig.colyseusServerAddress;\n            clone.colyseusServerPort = orig.colyseusServerPort;\n            clone.useSecureProtocol = orig.useSecureProtocol;\n            clone.SetRequestHeaders(orig.GetRequestHeaders());\n\n            return clone;\n        }\n\n        private string BuildWebRequestEndpoint()\n        {\n\t        UriBuilder webRequestEndpointBuilder = new UriBuilder(GetBaseEndpoint(GetWebRequestEndpointScheme()));\n\n\t        webRequestEndpointBuilder.Port = GetPort();\n\n\t        return webRequestEndpointBuilder.ToString();\n        }\n\n        private string BuildWebSocketEndpoint()\n        {\n\t        UriBuilder webSocketEndpointBuilder = new UriBuilder(GetBaseEndpoint(GetWebSocketEndpointScheme()));\n\n\t        webSocketEndpointBuilder.Port = GetPort();\n\n\t        return webSocketEndpointBuilder.ToString();\n        }\n\n        private string GetBaseEndpoint(string scheme)\n        {\n\t        return $\"{scheme}://{colyseusServerAddress}\";\n        }\n\n        public string GetWebSocketEndpointScheme()\n        {\n\t        return (useSecureProtocol ? \"wss\" : \"ws\");\n        }\n\n        public string GetWebRequestEndpointScheme()\n        {\n\t        return (useSecureProtocol ? \"https\" : \"http\");\n        }\n\n        public int GetPort()\n        {\n\t        if (ShouldIncludeServerPort() && int.TryParse(colyseusServerPort, out int serverPort))\n\t        {\n\t\t        return serverPort;\n\t        }\n\t        else\n\t        {\n\t\t        return -1;\n\t        }\n        }\n\n        private bool ShouldIncludeServerPort()\n        {\n\t        return !string.IsNullOrEmpty(colyseusServerPort) && !string.Equals(colyseusServerPort, \"80\") && !string.Equals(colyseusServerPort, \"443\");\n        }\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Settings/Settings.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 6ed729989615d4b4db072e1e8c41076c\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Settings.meta",
    "content": "fileFormatVersion: 2\nguid: 8fbeaff66f46edb4998d9d07492e454c\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Transport/WebSocket.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Colyseus\n{\n    public class WebSocketTransport\n    {\n        public event WebSocketOpenEventHandler OnOpen;\n        public event WebSocketMessageEventHandler OnMessage;\n        public event WebSocketErrorEventHandler OnError;\n        public event WebSocketCloseEventHandler OnClose;\n\n        private readonly object _dispatchLock = new object();\n        private NativeWebSocket.WebSocket _ws;\n        private bool _usesSharedDispatchLoop;\n\n        internal static bool ShouldUseSharedDispatchLoop(SynchronizationContext synchronizationContext)\n        {\n            return ColyseusContext.RegisterWebSocketForDispatch == null && synchronizationContext == null;\n        }\n\n        public async Task Connect(string url, Dictionary<string, string> headers)\n        {\n            var synchronizationContext = SynchronizationContext.Current;\n            var socket = new NativeWebSocket.WebSocket(url, headers);\n            _ws = socket;\n            _usesSharedDispatchLoop = false;\n\n            socket.OnOpen += () => OnOpen?.Invoke();\n            socket.OnMessage += (data) => OnMessage?.Invoke(data);\n            socket.OnError += (msg) => OnError?.Invoke(msg);\n            socket.OnClose += (code) =>\n            {\n                ColyseusContext.UnregisterWebSocketForDispatch?.Invoke(socket);\n#if !UNITY_WEBGL || UNITY_EDITOR\n                lock (_dispatchLock)\n                {\n                    _usesSharedDispatchLoop = false;\n                }\n\n                WebSocketDispatchLoop.Unregister(this);\n#endif\n                OnClose?.Invoke((int)code);\n            };\n\n            if (ColyseusContext.RegisterWebSocketForDispatch != null)\n            {\n                // External dispatcher (MonoGame, custom engine loop, etc.) handles DispatchMessageQueue\n                ColyseusContext.RegisterWebSocketForDispatch(socket);\n            }\n#if !UNITY_WEBGL || UNITY_EDITOR\n            else if (ShouldUseSharedDispatchLoop(synchronizationContext))\n            {\n                _usesSharedDispatchLoop = true;\n                WebSocketDispatchLoop.Register(this);\n            }\n#endif\n\n            await socket.Connect();\n        }\n\n        public Task Send(byte[] data) => _ws.Send(data);\n\n        public Task Close() => _ws.Close();\n\n        public void CancelConnection() => _ws.CancelConnection();\n\n#if !UNITY_WEBGL || UNITY_EDITOR\n        public void DispatchMessageQueue()\n        {\n            lock (_dispatchLock)\n            {\n                if (_usesSharedDispatchLoop)\n                {\n                    _usesSharedDispatchLoop = false;\n                    WebSocketDispatchLoop.Unregister(this);\n                }\n\n                _ws?.DispatchMessageQueue();\n            }\n        }\n\n        internal void DispatchMessageQueueFromSharedLoop()\n        {\n            lock (_dispatchLock)\n            {\n                if (!_usesSharedDispatchLoop)\n                {\n                    return;\n                }\n\n                _ws?.DispatchMessageQueue();\n            }\n        }\n#endif\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Transport/WebSocket.cs.meta",
    "content": "fileFormatVersion: 2\nguid: fc5122bd7006f4974b636c76af201f44"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Transport/WebSocketDispatchLoop.cs",
    "content": "#if !UNITY_WEBGL || UNITY_EDITOR\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\n\nnamespace Colyseus\n{\n    internal static class WebSocketDispatchLoop\n    {\n        private const int PollIntervalMilliseconds = 15;\n\n        private static readonly object SyncRoot = new object();\n        private static readonly HashSet<WebSocketTransport> Sockets = new HashSet<WebSocketTransport>();\n        private static readonly AutoResetEvent WakeUp = new AutoResetEvent(false);\n\n        private static Thread _dispatchThread;\n\n        public static void Register(WebSocketTransport socket)\n        {\n            if (socket == null)\n            {\n                return;\n            }\n\n            lock (SyncRoot)\n            {\n                if (!Sockets.Add(socket))\n                {\n                    return;\n                }\n\n                EnsureThread();\n            }\n\n            WakeUp.Set();\n        }\n\n        public static void Unregister(WebSocketTransport socket)\n        {\n            if (socket == null)\n            {\n                return;\n            }\n\n            lock (SyncRoot)\n            {\n                Sockets.Remove(socket);\n            }\n\n            WakeUp.Set();\n        }\n\n        private static void EnsureThread()\n        {\n            if (_dispatchThread != null)\n            {\n                return;\n            }\n\n            _dispatchThread = new Thread(DispatchLoop)\n            {\n                IsBackground = true,\n                Name = \"Colyseus.WebSocketDispatch\"\n            };\n            _dispatchThread.Start();\n        }\n\n        private static void DispatchLoop()\n        {\n            while (true)\n            {\n                WebSocketTransport[] sockets;\n\n                lock (SyncRoot)\n                {\n                    if (Sockets.Count == 0)\n                    {\n                        sockets = null;\n                    }\n                    else\n                    {\n                        sockets = new WebSocketTransport[Sockets.Count];\n                        Sockets.CopyTo(sockets);\n                    }\n                }\n\n                if (sockets == null)\n                {\n                    WakeUp.WaitOne();\n                    continue;\n                }\n\n                for (var i = 0; i < sockets.Length; i++)\n                {\n                    try\n                    {\n                        sockets[i].DispatchMessageQueueFromSharedLoop();\n                    }\n                    catch (Exception e)\n                    {\n                        ColyseusContext.Logger?.LogError($\"DispatchMessageQueue error: {e.Message}\");\n                    }\n                }\n\n                WakeUp.WaitOne(PollIntervalMilliseconds);\n            }\n        }\n    }\n}\n\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Transport/WebSocketDispatchLoop.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 368242dd6ccd74f16a7436c1c53f73ff"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Transport.meta",
    "content": "fileFormatVersion: 2\nguid: 2fc81b6cb1f8d4749a81f71f7b5a8d03\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/Exceptions.cs",
    "content": "using System;\n\nnamespace Colyseus\n{\n\t/// <summary>\n\t/// Custom exception thrown when there is an issue with Match Making\n\t/// </summary>\n\tpublic class MatchMakeException : Exception\n\t{\n\t\t/// <summary>\n\t\t/// The error code the server returned\n\t\t/// </summary>\n\t\tpublic int Code;\n\t\tpublic MatchMakeException(int code, string message) : base(message)\n\t\t{\n\t\t\tCode = code;\n\t\t}\n\t}\n\n\tpublic class HttpException : Exception\n\t{\n\t\t/// <summary>\n\t\t/// The error code the server returned\n\t\t/// </summary>\n\t\tpublic int StatusCode;\n\n\t\tpublic HttpException(int statusCode, string message) : base(message)\n\t\t{\n\t\t\tStatusCode = statusCode;\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/Exceptions.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ca772085cc5044b368171964c8140999\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/ExtensionMethods.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing UnityEngine;\nusing UnityEngine.Networking;\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Provides extension for Unity specific methods\n    /// </summary>\n    public static class ColyseusExtensionMethods\n    {\n        /// <summary>\n        ///     Returns our custom <see cref=\"UnityWebRequestAwaiter\" /> instead of a standard\n        ///     <see cref=\"UnityWebRequestAsyncOperation\" />\n        /// </summary>\n        /// <returns>An instance of <see cref=\"UnityWebRequestAwaiter\" /></returns>\n        public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)\n        {\n            return new UnityWebRequestAwaiter(asyncOp);\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/ExtensionMethods.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 49ca7a47d6d774afa802f5b302cd2f9f\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/ObjectExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     Extension methods for handling <see cref=\"IDictionary{TKey,TValue}\" /> and <see cref=\"object\" /> functionality\n    /// </summary>\n    public static class ColyseusObjectExtensions\n    {\n        /// <summary>\n        ///     Convert an <see cref=\"IDictionary{TKey,TValue}\" /> to an <see cref=\"object\" /> of type <typeparamref name=\"T\" />\n        /// </summary>\n        /// <param name=\"source\">The dictionary to be converted</param>\n        /// <typeparam name=\"T\">The type of <see cref=\"object\" /> we will convert this into</typeparam>\n        /// <returns>An <see cref=\"object\" /> of type <typeparamref name=\"T\" /></returns>\n        public static T ToObject<T>(this IDictionary<string, object> source)\n            where T : class, new()\n        {\n            T someObject = new T();\n            Type someObjectType = someObject.GetType();\n\n            foreach (KeyValuePair<string, object> item in source)\n            {\n                someObjectType\n                    .GetProperty(item.Key)\n                    ?.SetValue(someObject, item.Value, null);\n            }\n\n            return someObject;\n        }\n\n        /// <summary>\n        ///     Convert an <see cref=\"object\" /> into a <see cref=\"IDictionary{TKey,TValue}\"></see>\n        /// </summary>\n        /// <param name=\"source\">The <see cref=\"object\" /> to be converted</param>\n        /// <param name=\"bindingAttr\">The <see cref=\"BindingFlags\" /> to use on this <see cref=\"object\" /></param>\n        /// <returns>An <see cref=\"IDictionary{TKey,TValue}\" /> version of the <paramref name=\"source\" /></returns>\n        public static IDictionary<string, object> AsDictionary(this object source,\n            BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)\n        {\n            return source.GetType().GetProperties(bindingAttr).ToDictionary\n            (\n                propInfo => propInfo.Name,\n                propInfo => propInfo.GetValue(source, null)\n            );\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/ObjectExtensions.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 04fc7c8d440e04bc6afbdd8e8ceaab85\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/UnityWebRequestAwaiter.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing UnityEngine;\nusing UnityEngine.Networking;\n\nnamespace Colyseus\n{\n    /// <summary>\n    ///     A custom class that awaits the completion of a <see cref=\"UnityWebRequestAsyncOperation\" /> and then performs an\n    ///     <see cref=\"Action\" /> upon completion\n    /// </summary>\n    public class UnityWebRequestAwaiter : INotifyCompletion\n    {\n        private readonly UnityWebRequestAsyncOperation _asyncOp;\n        private Action _continuation;\n\n        public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)\n        {\n            _asyncOp = asyncOp;\n            asyncOp.completed += OnRequestCompleted;\n        }\n\n        /// <summary>\n        ///     Public getter to determine if the <see cref=\"UnityWebRequestAsyncOperation\" /> is completed\n        /// </summary>\n        public bool IsCompleted\n        {\n            get { return _asyncOp.isDone; }\n        }\n\n        /// <summary>\n        ///     Provide an action to be invoked when the <see cref=\"UnityWebRequestAsyncOperation\" /> s completed\n        /// </summary>\n        /// <param name=\"continuation\">The action to perform when the request is completed</param>\n        public void OnCompleted(Action continuation)\n        {\n            _continuation = continuation;\n        }\n\n        /// <summary>\n        ///     Satifies the <see cref=\"INotifyCompletion\" /> requirement, but currently unused\n        /// </summary>\n        public void GetResult()\n        {\n        }\n\n        private void OnRequestCompleted(AsyncOperation obj)\n        {\n            _continuation?.Invoke();\n        }\n    }\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils/UnityWebRequestAwaiter.cs.meta",
    "content": "fileFormatVersion: 2\nguid: eeaf5a5ece0b541c5af42f9c73275e1c\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus/Utils.meta",
    "content": "fileFormatVersion: 2\nguid: 9542be54dba5d9244aed15299f49540c\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Colyseus.meta",
    "content": "fileFormatVersion: 2\nguid: 1a26a17010d5aea49b8a4f09f5801b05\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/ColyseusSDK.asmdef",
    "content": "{\n\t\"name\": \"ColyseusSDK\",\n\t\"references\": [\n\t\t\"colyseus.nativewebsocket\"\n\t]\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/ColyseusSDK.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: 7d8788162c0190c4c8b801543ada1607\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Editor Default Resources/.gitkeep",
    "content": ""
  },
  {
    "path": "Assets/Colyseus/Runtime/Editor Default Resources/Icons/ColyseusSettings.png.import",
    "content": "[remap]\n\nimporter=\"texture\"\ntype=\"CompressedTexture2D\"\nuid=\"uid://c6t3i2w508an0\"\npath=\"res://.godot/imported/ColyseusSettings.png-b62bac3a69932db7348b37a35909416f.ctex\"\nmetadata={\n\"vram_texture\": false\n}\n\n[deps]\n\nsource_file=\"res://ColyseusSDK/Editor Default Resources/Icons/ColyseusSettings.png\"\ndest_files=[\"res://.godot/imported/ColyseusSettings.png-b62bac3a69932db7348b37a35909416f.ctex\"]\n\n[params]\n\ncompress/mode=0\ncompress/high_quality=false\ncompress/lossy_quality=0.7\ncompress/uastc_level=0\ncompress/rdo_quality_loss=0.0\ncompress/hdr_compression=1\ncompress/normal_map=0\ncompress/channel_pack=0\nmipmaps/generate=false\nmipmaps/limit=-1\nroughness/mode=0\nroughness/src_normal=\"\"\nprocess/channel_remap/red=0\nprocess/channel_remap/green=1\nprocess/channel_remap/blue=2\nprocess/channel_remap/alpha=3\nprocess/fix_alpha_border=true\nprocess/premult_alpha=false\nprocess/normal_map_invert_y=false\nprocess/hdr_as_srgb=false\nprocess/hdr_clamp_exposure=false\nprocess/size_limit=0\ndetect_3d/compress_to=1\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Editor Default Resources/Icons/ColyseusSettings.png.import.meta",
    "content": "fileFormatVersion: 2\nguid: 40daac54efc2241099dc969333714022\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Editor Default Resources/Icons/ColyseusSettings.png.meta",
    "content": "fileFormatVersion: 2\nguid: 0d890485a241f1c478e0dd5844695a6f\nTextureImporter:\n  internalIDToNameTable: []\n  externalObjects: {}\n  serializedVersion: 12\n  mipmaps:\n    mipMapMode: 0\n    enableMipMap: 0\n    sRGBTexture: 1\n    linearTexture: 0\n    fadeOut: 0\n    borderMipMap: 0\n    mipMapsPreserveCoverage: 0\n    alphaTestReferenceValue: 0.5\n    mipMapFadeDistanceStart: 1\n    mipMapFadeDistanceEnd: 3\n  bumpmap:\n    convertToNormalMap: 0\n    externalNormalMap: 0\n    heightScale: 0.25\n    normalMapFilter: 0\n  isReadable: 0\n  streamingMipmaps: 0\n  streamingMipmapsPriority: 0\n  vTOnly: 0\n  ignoreMasterTextureLimit: 0\n  grayScaleToAlpha: 0\n  generateCubemap: 6\n  cubemapConvolution: 0\n  seamlessCubemap: 0\n  textureFormat: 1\n  maxTextureSize: 2048\n  textureSettings:\n    serializedVersion: 2\n    filterMode: 1\n    aniso: 1\n    mipBias: 0\n    wrapU: 1\n    wrapV: 1\n    wrapW: 0\n  nPOTScale: 0\n  lightmap: 0\n  compressionQuality: 50\n  spriteMode: 1\n  spriteExtrude: 1\n  spriteMeshType: 1\n  alignment: 0\n  spritePivot: {x: 0.5, y: 0.5}\n  spritePixelsToUnits: 100\n  spriteBorder: {x: 0, y: 0, z: 0, w: 0}\n  spriteGenerateFallbackPhysicsShape: 0\n  alphaUsage: 1\n  alphaIsTransparency: 1\n  spriteTessellationDetail: -1\n  textureType: 2\n  textureShape: 1\n  singleChannelComponent: 0\n  flipbookRows: 1\n  flipbookColumns: 1\n  maxTextureSizeSet: 0\n  compressionQualitySet: 0\n  textureFormatSet: 0\n  ignorePngGamma: 0\n  applyGammaDecoding: 0\n  cookieLightType: 1\n  platformSettings:\n  - serializedVersion: 3\n    buildTarget: DefaultTexturePlatform\n    maxTextureSize: 128\n    resizeAlgorithm: 0\n    textureFormat: -1\n    textureCompression: 1\n    compressionQuality: 50\n    crunchedCompression: 0\n    allowsAlphaSplitting: 0\n    overridden: 0\n    androidETC2FallbackOverride: 0\n    forceMaximumCompressionQuality_BC6H_BC7: 0\n  - serializedVersion: 3\n    buildTarget: Standalone\n    maxTextureSize: 128\n    resizeAlgorithm: 0\n    textureFormat: -1\n    textureCompression: 1\n    compressionQuality: 50\n    crunchedCompression: 0\n    allowsAlphaSplitting: 0\n    overridden: 0\n    androidETC2FallbackOverride: 0\n    forceMaximumCompressionQuality_BC6H_BC7: 0\n  - serializedVersion: 3\n    buildTarget: Android\n    maxTextureSize: 128\n    resizeAlgorithm: 0\n    textureFormat: -1\n    textureCompression: 1\n    compressionQuality: 50\n    crunchedCompression: 0\n    allowsAlphaSplitting: 0\n    overridden: 0\n    androidETC2FallbackOverride: 0\n    forceMaximumCompressionQuality_BC6H_BC7: 0\n  - serializedVersion: 3\n    buildTarget: WebGL\n    maxTextureSize: 128\n    resizeAlgorithm: 0\n    textureFormat: -1\n    textureCompression: 1\n    compressionQuality: 50\n    crunchedCompression: 0\n    allowsAlphaSplitting: 0\n    overridden: 0\n    androidETC2FallbackOverride: 0\n    forceMaximumCompressionQuality_BC6H_BC7: 0\n  - serializedVersion: 3\n    buildTarget: Server\n    maxTextureSize: 128\n    resizeAlgorithm: 0\n    textureFormat: -1\n    textureCompression: 1\n    compressionQuality: 50\n    crunchedCompression: 0\n    allowsAlphaSplitting: 0\n    overridden: 0\n    androidETC2FallbackOverride: 0\n    forceMaximumCompressionQuality_BC6H_BC7: 0\n  spriteSheet:\n    serializedVersion: 2\n    sprites: []\n    outline: []\n    physicsShape: []\n    bones: []\n    spriteID: \n    internalID: 0\n    vertices: []\n    indices: \n    edges: []\n    weights: []\n    secondaryTextures: []\n    nameFileIdTable: {}\n  spritePackingTag: \n  pSDRemoveMatte: 0\n  pSDShowRemoveMatteOption: 0\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Editor Default Resources/Icons.meta",
    "content": "fileFormatVersion: 2\nguid: 1af14f53b56f41e4b95a1e6089cea2e6\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Editor Default Resources.meta",
    "content": "fileFormatVersion: 2\nguid: 78d7e3c75054b9b4abf1814a70fe3695\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example.meta",
    "content": "fileFormatVersion: 2\nguid: ae74ab3446648452aa052bfb9ad976e8\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/ColyseusNetworkManager.cs",
    "content": "using System.Collections.Generic;\nusing System.Threading.Tasks;\nusing UnityEngine;\nusing Colyseus;\n\npublic class WeatherMessage {\n  public string weather;\n}\n\npublic class ColyseusNetworkManager : MonoBehaviour\n{\n  protected Client client;\n  protected Room<MyRoomState> room;\n\n  protected Room<NoState> lobbyRoom;\n\n  protected Room<NoState> queueRoom;\n  // Start is called before the first frame update\n  void Start()\n  {\n    client = new Client(\"ws://localhost:2567\");\n\n    //\n    // join \"my_room\" and bind callbacks\n    // ------------------------------------------------------------\n    // this is the main game room demonstration, with messages and state callbacks\n    //\n    joinMyRoom();\n\n    //\n    // join \"lobby\" room and bind callbacks\n    // ------------------------------------------------------------\n    // when creating or destroying \"my_room\" rooms, the \"lobby\" room will receive these events\n    //\n    joinLobbyRoom();\n\n    //\n    // join \"queue\" room and bind callbacks\n    // ------------------------------------------------------------\n    // the \"queue\" room requires 4 clients to join the game room\n    // you can open the playground at http://localhost:2567, and join the \"queue\" room 3 times to test it\n    //\n    joinQueueRoom();\n  }\n\n  // Update is called once per frame\n  void Update()\n  {\n\n  }\n\n  async void OnDestroy()\n  {\n    // Close all room connections when the MonoBehaviour is destroyed\n    // (e.g., when stopping play mode in the Editor)\n    if (room != null) await room.Leave();\n    if (lobbyRoom != null) await lobbyRoom.Leave();\n    if (queueRoom != null) await queueRoom.Leave();\n  }\n\n  protected async void joinMyRoom()\n  {\n    var options = new Dictionary<string, object>();\n    room = await client.JoinOrCreate<MyRoomState>(\"my_room\", options);\n\n    // Allow to reconnect immediately\n    room.Reconnection.MinUptime = 0;\n\n    room.OnLeave += (int code) => {\n      Debug.Log($\"[MyRoom] Left room with code: {code}\");\n    };\n\n    //\n    // messages from server\n    //\n    room.OnMessage(\"weather\", (WeatherMessage message) =>\n    {\n      Debug.Log($\"[MyRoom] Weather changed: {message.weather}\");\n    });\n\n    //\n    // state callbacks\n    //\n    var callbacks = Colyseus.Schema.Callbacks.Get(room);\n\n    callbacks.OnAdd(state => state.players, (key, player) =>\n    {\n      Debug.Log($\"[MyRoom] Player {key} joined the room\");\n\n      callbacks.OnChange(player, () =>\n      {\n        Debug.Log($\"[MyRoom] Player {key} changed!\");\n      });\n\n      callbacks.Listen(player, player => player.x, (x, _) => {\n        Debug.Log($\"[MyRoom] Player {key} moved to {x}\");\n      });\n\n      callbacks.Listen(player, player => player.y, (y, _) => {\n        Debug.Log($\"[MyRoom] Player {key} moved to {y}\");\n      });\n    });\n\n    callbacks.OnRemove(state => state.players, (key, player) =>\n    {\n      Debug.Log($\"[MyRoom] Player {key} left the room\");\n    });\n  }\n\n  protected async void joinLobbyRoom()\n  {\n    lobbyRoom = await client.JoinOrCreate(\"lobby\");\n\n    lobbyRoom.OnMessage(\"rooms\", (RoomAvailable[] message) =>\n    {\n      Debug.Log($\"[Lobby] Rooms: {message}\");\n    });\n\n    lobbyRoom.OnMessage(\"+\", (object[] message) =>\n    {\n      string roomId = (string)message[0];\n      var roomData = (IDictionary<string, object>)message[1];\n      Debug.Log($\"[Lobby] Add Room: {roomId} - {roomData[\"name\"]} ({roomData[\"clients\"]}/{roomData[\"maxClients\"]})\");\n    });\n\n    lobbyRoom.OnMessage(\"-\", (string message) =>\n    {\n      Debug.Log($\"[Lobby] Remove Room: {message}\");\n    });\n\n  }\n\n  protected async void joinQueueRoom()\n  {\n    queueRoom = await client.JoinOrCreate(\"queue\");\n\n    queueRoom.OnMessage(\"clients\", (int clients) =>\n    {\n      Debug.Log($\"[Queue] Clients: {clients}\");\n    });\n\n    queueRoom.OnMessage(\"seat\", async (SeatReservation seat) => {\n      Debug.Log($\"[Queue] Seat: {seat.roomId} - {seat.sessionId} - {seat.publicAddress} - {seat.processId} - {seat.reconnectionToken} - {seat.devMode} - {seat.protocol}\");\n\n      var room = await client.ConsumeSeatReservation<MyRoomState>(seat);\n\n      Debug.Log($\"[Queue] Joined game room: {room.RoomId}\");\n\n      room.OnLeave += (int code) => {\n        Debug.Log($\"[Queue] Left game room: {code}\");\n      };\n\n      // confirm successfully joined the room! / leave the queue room\n      _ = queueRoom.Send(\"confirm\");\n\n      // delay 1 second\n      _ = Task.Delay(500);\n\n      //\n      // queue demo is over, leave the room\n      // (you should actually bind the callbacks for the room and not leave it here)\n      //\n      _ = room.Leave();\n    });\n\n    queueRoom.OnLeave += (int code) => {\n      Debug.Log($\"[Queue] Left queue room: {code}\");\n    };\n\n  }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/ColyseusNetworkManager.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 9ca8e2dc39ba1406a8d548cecca16bde\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/ConnectionManager.cs",
    "content": "using System.Collections;\nusing System.Collections.Generic;\nusing UnityEngine;\n\npublic class ConnectionManager : MonoBehaviour\n{\n    // Start is called before the first frame update\n    void Start()\n    {\n        \n    }\n\n    // Update is called once per frame\n    void Update()\n    {\n        \n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/ConnectionManager.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 3ca02083085144590ae17a25ce46df36\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/ExampleScene.unity.meta",
    "content": "fileFormatVersion: 2\nguid: c6a63a8be1d1044869c7ef0d1a91dde4\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/MyServerSettings.asset.meta",
    "content": "fileFormatVersion: 2\nguid: c63116ed08d6d405985d628d4aeb2820\nNativeFormatImporter:\n  externalObjects: {}\n  mainObjectFileID: 11400000\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema/Item.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 4.0.7\n// \n\nusing Colyseus.Schema;\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine.Scripting;\n#endif\n\npublic partial class Item : Schema {\n#if UNITY_5_3_OR_NEWER\n[Preserve]\n#endif\npublic Item() { }\n\t[Type(0, \"string\")]\n\tpublic string name = default(string);\n\n\t[Type(1, \"number\")]\n\tpublic float value = default(float);\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema/Item.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1add4259764d34d94bf8be13e98a69ca"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema/MyRoomState.cs",
    "content": "//\n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n//\n// GENERATED USING @colyseus/schema 4.0.7\n//\n\nusing Colyseus.Schema;\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine.Scripting;\n#endif\n\npublic partial class MyRoomState : Schema {\n#if UNITY_5_3_OR_NEWER\n[Preserve]\n#endif\npublic MyRoomState() { }\n\t[Type(0, \"map\", typeof(MapSchema<Player>))]\n\tpublic MapSchema<Player> players = null;\n\n\t[Type(1, \"ref\", typeof(Player))]\n\tpublic Player host = null;\n\n\t[Type(2, \"string\")]\n\tpublic string currentTurn = default(string);\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema/MyRoomState.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8ae9c4a2670084d28843c4b84c3dd530"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 4.0.7\n// \n\nusing Colyseus.Schema;\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine.Scripting;\n#endif\n\npublic partial class Player : Schema {\n#if UNITY_5_3_OR_NEWER\n[Preserve]\n#endif\npublic Player() { }\n\t[Type(0, \"number\")]\n\tpublic float x = default(float);\n\n\t[Type(1, \"number\")]\n\tpublic float y = default(float);\n\n\t[Type(2, \"boolean\")]\n\tpublic bool isBot = default(bool);\n\n\t[Type(3, \"boolean\")]\n\tpublic bool disconnected = default(bool);\n\n\t[Type(4, \"array\", typeof(ArraySchema<Item>))]\n\tpublic ArraySchema<Item> items = null;\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 74cbd8724747e4d2092e580e14725b78"
  },
  {
    "path": "Assets/Colyseus/Runtime/Example~/Schema.meta",
    "content": "fileFormatVersion: 2\nguid: a80dec46085bf4ea4b523a69ff3f2405\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/ArrayExtensions.cs",
    "content": "using System;\nnamespace GameDevWare.Serialization\n{\n\tinternal static class ArrayExtensions\n\t{\n\t\tpublic static OutputT[] ConvertAll<T, OutputT>(this T[] array, Func<T, OutputT> converter)\n\t\t{\n\t\t\tif (array == null) throw new ArgumentNullException(\"array\");\n\t\t\tif (converter == null) throw new ArgumentNullException(\"converter\");\n\n\t\t\tvar newList = new OutputT[array.Length];\n\t\t\tvar i = 0;\n\t\t\tforeach (var item in array)\n\t\t\t{\n\t\t\t\tnewList[i++] = converter(item);\n\t\t\t}\n\t\t\treturn newList;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/ArrayExtensions.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: b7ce8c517c054bd5bec836e71944c782\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/GenerateTypeSerializerAttribute.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\t[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]\n\tpublic class GenerateTypeSerializerAttribute : Attribute\n\t{\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/GenerateTypeSerializerAttribute.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 8420b011fc234497996f0dd94bd8b466\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IJsonReader.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic interface IJsonReader\n\t{\n\t\tSerializationContext Context { get; }\n\n\t\tJsonToken Token { get; }\n\t\tobject RawValue { get; }\n\t\tIValueInfo Value { get; }\n\n\t\tbool NextToken();\n\n\t\tbool IsEndOfStream();\n\n\t\t/// <summary>\n\t\t///     Resets Line/Column numbers, CharactersRead and Token information of reader\n\t\t/// </summary>\n\t\tvoid Reset();\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IJsonReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 9e6240f54909465fb6d01ab74fa0061d\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IJsonWriter.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic interface IJsonWriter\n\t{\n\t\tSerializationContext Context { get; }\n\n\t\tvoid Flush();\n\n\t\tvoid Write(string value);\n\t\tvoid Write(JsonMember value);\n\t\tvoid Write(int number);\n\t\tvoid Write(uint number);\n\t\tvoid Write(long number);\n\t\tvoid Write(ulong number);\n\t\tvoid Write(float number);\n\t\tvoid Write(double number);\n\t\tvoid Write(decimal number);\n\t\tvoid Write(bool value);\n\t\tvoid Write(DateTime dateTime);\n\t\tvoid Write(DateTimeOffset dateTimeOffset);\n\t\tvoid WriteObjectBegin(int numberOfMembers);\n\t\tvoid WriteObjectEnd();\n\t\tvoid WriteArrayBegin(int numberOfMembers);\n\t\tvoid WriteArrayEnd();\n\t\tvoid WriteNull();\n\n\t\tvoid WriteJson(string jsonString);\n\t\tvoid WriteJson(char[] jsonString, int index, int charCount);\n\n\t\tvoid Reset();\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IJsonWriter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 633fb2c48abf4347a8ffe33fafa2ce00\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IValueInfo.cs",
    "content": "﻿using System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic interface IValueInfo\n\t{\n\t\tbool HasValue { get; }\n\t\tobject Raw { get; }\n\t\tType Type { get; }\n\t\tbool AsBoolean { get; }\n\t\tbyte AsByte { get; }\n\t\tshort AsInt16 { get; }\n\t\tint AsInt32 { get; }\n\t\tlong AsInt64 { get; }\n\t\tsbyte AsSByte { get; }\n\t\tushort AsUInt16 { get; }\n\t\tuint AsUInt32 { get; }\n\t\tulong AsUInt64 { get; }\n\t\tfloat AsSingle { get; }\n\t\tdouble AsDouble { get; }\n\t\tdecimal AsDecimal { get; }\n\t\tstring AsString { get; }\n\t\tDateTime AsDateTime { get; }\n\n\t\tint LineNumber { get; }\n\t\tint ColumnNumber { get; }\n\t}\n}"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IValueInfo.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 08a9e5333be7414aa0de623e9026075e\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IndexedDictionary.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\t[Serializable, DebuggerDisplay(\"IndexedDictionary, Count: {Count}\")]\n\tpublic class IndexedDictionary<KeyT, ValueT> : IDictionary<KeyT, ValueT>, IDictionary\n\t{\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]\n\t\tprivate readonly Dictionary<KeyT, ValueT> dictionary;\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tprivate readonly List<KeyT> keys;\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never), NonSerialized]\n\t\tprivate ReadOnlyCollection<KeyT> keysReadOnly;\n\n\t\t/// <inheritdoc />\n\t\tpublic int Count { get { return this.dictionary.Count; } }\n\n\t\t/// <inheritdoc />\n\t\tpublic ValueT this[KeyT key]\n\t\t{\n\t\t\tget { return this.dictionary[key]; }\n\t\t\tset\n\t\t\t{\n\t\t\t\tif (this.dictionary.ContainsKey(key) == false)\n\t\t\t\t\tthis.keys.Add(key);\n\t\t\t\tthis.dictionary[key] = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tobject IDictionary.this[object key]\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tvar value = default(ValueT);\n\t\t\t\treturn this.TryGetValue((KeyT)key, out value) ? value : default(object);\n\t\t\t}\n\t\t\tset { this[(KeyT)key] = (ValueT)value; }\n\t\t}\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tobject ICollection.SyncRoot { get { return this.dictionary; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tbool ICollection.IsSynchronized { get { return false; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tpublic ReadOnlyCollection<KeyT> Keys { get { return this.keysReadOnly ?? (this.keysReadOnly = new ReadOnlyCollection<KeyT>(this.keys)); } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tpublic ReadOnlyCollection<ValueT> Values { get { return this.GetValues(); } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tICollection IDictionary.Values { get { return this.GetValues(); } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tICollection IDictionary.Keys { get { return this.keys; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tbool IDictionary.IsReadOnly { get { return false; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tbool IDictionary.IsFixedSize { get { return false; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tbool ICollection<KeyValuePair<KeyT, ValueT>>.IsReadOnly { get { return false; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tICollection<KeyT> IDictionary<KeyT, ValueT>.Keys { get { return this.keysReadOnly; } }\n\t\t/// <inheritdoc />\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\tICollection<ValueT> IDictionary<KeyT, ValueT>.Values { get { return this.GetValues(); } }\n\n\t\tpublic IndexedDictionary()\n\t\t{\n\t\t\tthis.dictionary = new Dictionary<KeyT, ValueT>();\n\t\t\tthis.keys = new List<KeyT>();\n\t\t\tthis.keysReadOnly = new ReadOnlyCollection<KeyT>(this.keys);\n\t\t}\n\t\tpublic IndexedDictionary(int count)\n\t\t{\n\t\t\tif (count < 0) throw new ArgumentOutOfRangeException(\"count\");\n\n\t\t\tif (count == 0) count = 30;\n\n\t\t\tthis.dictionary = new Dictionary<KeyT, ValueT>(count);\n\t\t\tthis.keys = new List<KeyT>(count);\n\t\t\tthis.keysReadOnly = new ReadOnlyCollection<KeyT>(this.keys);\n\t\t}\n\t\tpublic IndexedDictionary(IDictionary<KeyT, ValueT> dictionary)\n\t\t{\n\t\t\tif (dictionary == null) throw new ArgumentNullException(\"dictionary\");\n\n\t\t\tthis.dictionary = new Dictionary<KeyT, ValueT>(dictionary);\n\t\t\tthis.keys = new List<KeyT>(dictionary.Keys);\n\t\t\tthis.keysReadOnly = new ReadOnlyCollection<KeyT>(this.keys);\n\t\t}\n\t\tpublic IndexedDictionary(IEnumerable<KeyValuePair<KeyT, ValueT>> pairs)\n\t\t{\n\t\t\tif (pairs == null) throw new ArgumentNullException(\"pairs\");\n\n\t\t\tthis.dictionary = new Dictionary<KeyT, ValueT>();\n\t\t\tthis.keys = new List<KeyT>();\n\t\t\tthis.keysReadOnly = new ReadOnlyCollection<KeyT>(this.keys);\n\n\t\t\tforeach (var pair in pairs)\n\t\t\t\tthis.Add(pair.Key, pair.Value);\n\t\t}\n\t\tpublic IndexedDictionary(IDictionary<KeyT, ValueT> dictionary, ICollection<KeyT> keys)\n\t\t{\n\t\t\tif (dictionary == null) throw new ArgumentNullException(\"dictionary\");\n\t\t\tif (keys == null) throw new ArgumentNullException(\"keys\");\n\n\n\t\t\tthis.dictionary = new Dictionary<KeyT, ValueT>(dictionary);\n\t\t\tthis.keys = new List<KeyT>(keys);\n\t\t\tthis.keysReadOnly = new ReadOnlyCollection<KeyT>(this.keys);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic void Add(KeyT key, ValueT value)\n\t\t{\n\t\t\tthis.dictionary.Add(key, value);\n\t\t\tthis.keys.Add(key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic void Add(IndexedDictionary<KeyT, ValueT> other)\n\t\t{\n\t\t\tif (other == null) throw new ArgumentNullException(\"other\");\n\n\t\t\tif (this.Count == 0)\n\t\t\t{\n\t\t\t\tthis.keys.AddRange(other.keys);\n\t\t\t\tforeach (var kv in other.dictionary)\n\t\t\t\t\tthis.dictionary.Add(kv.Key, kv.Value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var kv in other.dictionary)\n\t\t\t\t{\n\t\t\t\t\tthis.dictionary.Add(kv.Key, kv.Value);\n\t\t\t\t\tthis.keys.Add(kv.Key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic void Insert(int index, KeyT key, ValueT value)\n\t\t{\n\t\t\t// Dictionary operation first, so exception thrown if key already exists.\n\t\t\tthis.dictionary.Add(key, value);\n\t\t\tthis.keys.Insert(index, key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic bool ContainsKey(KeyT key)\n\t\t{\n\t\t\treturn this.dictionary.ContainsKey(key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic bool ContainsKey(KeyT key, IEqualityComparer<KeyT> keyComparer)\n\t\t{\n\t\t\tforeach (var k in this.keys)\n\t\t\t\tif (keyComparer.Equals(k, key))\n\t\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic bool ContainsValue(ValueT value)\n\t\t{\n\t\t\tforeach (var kv in this.dictionary)\n\t\t\t\tif (Equals(value, kv.Value))\n\t\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic bool ContainsValue(ValueT value, IEqualityComparer comparer)\n\t\t{\n\t\t\tif (comparer == null) throw new ArgumentNullException(\"comparer\");\n\n\t\t\tforeach (var kv in this.dictionary)\n\t\t\t\tif (comparer.Equals(value, kv.Value))\n\t\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic bool Remove(KeyT key)\n\t\t{\n\t\t\tvar wasInDictionary = this.dictionary.Remove(key);\n\t\t\tthis.keys.Remove(key);\n\n\t\t\treturn wasInDictionary;\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic bool TryGetValue(KeyT key, out ValueT value)\n\t\t{\n\t\t\treturn this.dictionary.TryGetValue(key, out value);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic int IndexOf(KeyT key)\n\t\t{\n\t\t\treturn this.keys.IndexOf(key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic void RemoveAt(int index)\n\t\t{\n\t\t\tif (index >= this.Count || index < 0) throw new ArgumentOutOfRangeException(\"index\");\n\n\t\t\tvar key = this.keys[index];\n\t\t\tthis.dictionary.Remove(key);\n\t\t\tthis.keys.RemoveAt(index);\n\t\t}\n\t\tpublic void SortKeys(IComparer<KeyT> comparer)\n\t\t{\n\t\t\tif (comparer == null) throw new ArgumentNullException(\"comparer\");\n\n\t\t\tthis.keys.Sort(comparer);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic void Clear()\n\t\t{\n\t\t\tthis.dictionary.Clear();\n\t\t\tthis.keys.Clear();\n\t\t}\n\n\t\tprivate ReadOnlyCollection<ValueT> GetValues()\n\t\t{\n\t\t\tvar values = new ValueT[this.Count];\n\t\t\tvar index = 0;\n\t\t\tforeach (var key in this.keys)\n\t\t\t\tvalues[index++] = this.dictionary[key];\n\t\t\treturn new ReadOnlyCollection<ValueT>(values);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tbool IDictionary.Contains(object key)\n\t\t{\n\t\t\treturn this.ContainsKey((KeyT)key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tvoid IDictionary.Add(object key, object value)\n\t\t{\n\t\t\tthis.Add((KeyT)key, (ValueT)value);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tIDictionaryEnumerator IDictionary.GetEnumerator()\n\t\t{\n\t\t\treturn this.GetEnumerator();\n\t\t}\n\t\t/// <inheritdoc />\n\t\tvoid IDictionary.Remove(object key)\n\t\t{\n\t\t\tthis.Remove((KeyT)key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tvoid ICollection.CopyTo(Array array, int index)\n\t\t{\n\t\t\tif (array == null) throw new ArgumentNullException(\"array\");\n\t\t\tif (index >= array.Length) throw new ArgumentOutOfRangeException(\"index\");\n\t\t\tif (index + this.Count > array.Length) throw new ArgumentOutOfRangeException(\"index\");\n\n\t\t\tvar end = index + this.Count;\n\t\t\tfor (var i = 0; i < end; i++)\n\t\t\t\tarray.SetValue(new DictionaryEntry(this.keys[i], this.dictionary[this.keys[i]]), index + i);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tvoid ICollection<KeyValuePair<KeyT, ValueT>>.Add(KeyValuePair<KeyT, ValueT> item)\n\t\t{\n\t\t\tthis.Add(item.Key, item.Value);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tbool ICollection<KeyValuePair<KeyT, ValueT>>.Contains(KeyValuePair<KeyT, ValueT> item)\n\t\t{\n\t\t\tvar value = default(ValueT);\n\t\t\treturn this.dictionary.TryGetValue(item.Key, out value) && Equals(value, item.Value);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tvoid ICollection<KeyValuePair<KeyT, ValueT>>.CopyTo(KeyValuePair<KeyT, ValueT>[] array, int arrayIndex)\n\t\t{\n\t\t\tforeach (var pair in this)\n\t\t\t{\n\t\t\t\tarray[arrayIndex] = pair;\n\t\t\t\tarrayIndex++;\n\t\t\t}\n\n\t\t}\n\t\t/// <inheritdoc />\n\t\tbool ICollection<KeyValuePair<KeyT, ValueT>>.Remove(KeyValuePair<KeyT, ValueT> item)\n\t\t{\n\t\t\tif (!this.Contains(item))\n\t\t\t\treturn false;\n\n\t\t\treturn this.Remove(item.Key);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tIEnumerator<KeyValuePair<KeyT, ValueT>> IEnumerable<KeyValuePair<KeyT, ValueT>>.GetEnumerator()\n\t\t{\n\t\t\treturn this.GetEnumerator();\n\t\t}\n\t\t/// <inheritdoc />\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn this.GetEnumerator();\n\t\t}\n\n\t\tpublic Enumerator GetEnumerator()\n\t\t{\n\t\t\treturn new Enumerator(this);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"Count: \" + this.Count.ToString();\n\t\t}\n\n\t\tpublic struct Enumerator : IEnumerator<KeyValuePair<KeyT, ValueT>>, IDictionaryEnumerator\n\t\t{\n\t\t\tprivate List<KeyT>.Enumerator innerEnumerator;\n\t\t\tprivate readonly IndexedDictionary<KeyT, ValueT> owner;\n\t\t\tprivate KeyValuePair<KeyT, ValueT> current;\n\n\t\t\tpublic Enumerator(IndexedDictionary<KeyT, ValueT> owner)\n\t\t\t{\n\t\t\t\tthis.owner = owner;\n\t\t\t\tthis.innerEnumerator = owner.keys.GetEnumerator();\n\t\t\t\tthis.current = new KeyValuePair<KeyT, ValueT>();\n\t\t\t}\n\n\t\t\t/// <inheritdoc />\n\t\t\tpublic object Key { get { return this.current.Key; } }\n\t\t\t/// <inheritdoc />\n\t\t\tpublic object Value { get { return this.current.Value; } }\n\t\t\t/// <inheritdoc />\n\t\t\tpublic DictionaryEntry Entry { get { return new DictionaryEntry(this.current.Key, this.current.Value); } }\n\t\t\t/// <inheritdoc />\n\t\t\tpublic KeyValuePair<KeyT, ValueT> Current { get { return this.current; } }\n\t\t\t/// <inheritdoc />\n\t\t\tobject IEnumerator.Current { get { return this.Entry; } }\n\n\t\t\t/// <inheritdoc />\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tif (!this.innerEnumerator.MoveNext())\n\t\t\t\t\treturn false;\n\n\t\t\t\tvar key = this.innerEnumerator.Current;\n\t\t\t\tthis.current = new KeyValuePair<KeyT, ValueT>(key, this.owner.dictionary[key]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t/// <inheritdoc />\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthis.innerEnumerator = this.owner.keys.GetEnumerator();\n\t\t\t}\n\t\t\t/// <inheritdoc />\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthis.innerEnumerator.Dispose();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/IndexedDictionary.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 37db542680ca413d96e9d3920576ea8a\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Json.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\nusing GameDevWare.Serialization.MessagePack;\nusing GameDevWare.Serialization.Serializers;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic static class Json\n\t{\n\n\t\tprivate static IFormatProvider _DefaultFormat = CultureInfo.InvariantCulture;\n\t\tprivate static Encoding _DefaultEncoding = new UTF8Encoding(false, true);\n\t\tprivate static string[] _DefaultDateTimeFormats;\n\n\t\tpublic static string[] DefaultDateTimeFormats\n\t\t{\n\t\t\tget { return _DefaultDateTimeFormats; }\n\t\t\tset\n\t\t\t{\n\t\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\t\t\t\tif (value.Length == 0) throw new ArgumentException();\n\n\t\t\t\t_DefaultDateTimeFormats = value;\n\t\t\t}\n\t\t}\n\t\tpublic static IFormatProvider DefaultFormat\n\t\t{\n\t\t\tget { return _DefaultFormat; }\n\t\t\tset\n\t\t\t{\n\t\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\t\t_DefaultFormat = value;\n\t\t\t}\n\t\t}\n\t\tpublic static Encoding DefaultEncoding\n\t\t{\n\t\t\tget { return _DefaultEncoding; }\n\t\t\tset\n\t\t\t{\n\t\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\t\t_DefaultEncoding = value;\n\t\t\t}\n\t\t}\n\t\tpublic static List<TypeSerializer> DefaultSerializers { get; private set; }\n\n\t\tstatic Json()\n\t\t{\n\t\t\t// ReSharper disable StringLiteralTypo\n\t\t\t_DefaultDateTimeFormats = new[]\n\t\t\t{\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.fffzzz\", // ISO 8601, with timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.ffzzz\", // ISO 8601, with timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.fzzz\", // ISO 8601, with timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ssZ\", // also ISO 8601, without timezone and without microseconds\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.fZ\", // also ISO 8601, without timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.ffZ\", // also ISO 8601, without timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.fffZ\", // also ISO 8601, without timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.ffffZ\", // also ISO 8601, without timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.fffffZ\", // also ISO 8601, without timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.ffffffZ\", // also ISO 8601, without timezone\n\t\t\t\t\"yyyy-MM-ddTHH:mm:ss.fffffffZ\" // also ISO 8601, without timezone\n\t\t\t};\n\t\t\t// ReSharper restore StringLiteralTypo\n\n\t\t\tDefaultSerializers = new List<TypeSerializer>\n\t\t\t{\n\t\t\t\tnew BinarySerializer(),\n\t\t\t\tnew DateTimeOffsetSerializer(),\n\t\t\t\tnew DateTimeSerializer(),\n\t\t\t\tnew GuidSerializer(),\n\t\t\t\tnew StreamSerializer(),\n\t\t\t\tnew UriSerializer(),\n\t\t\t\tnew VersionSerializer(),\n\t\t\t\tnew TimeSpanSerializer(),\n\t\t\t\tnew DictionaryEntrySerializer(),\n\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\n\t\t\t\tnew BoundsSerializer(),\n\t\t\t\tnew Matrix4x4Serializer(),\n\t\t\t\tnew QuaternionSerializer(),\n\t\t\t\tnew RectSerializer(),\n\t\t\t\tnew Vector2Serializer(),\n\t\t\t\tnew Vector3Serializer(),\n\t\t\t\tnew Vector4Serializer(),\n#endif\n\t\t\t\tnew PrimitiveSerializer(typeof (bool)),\n\t\t\t\tnew PrimitiveSerializer(typeof (byte)),\n\t\t\t\tnew PrimitiveSerializer(typeof (decimal)),\n\t\t\t\tnew PrimitiveSerializer(typeof (double)),\n\t\t\t\tnew PrimitiveSerializer(typeof (short)),\n\t\t\t\tnew PrimitiveSerializer(typeof (int)),\n\t\t\t\tnew PrimitiveSerializer(typeof (long)),\n\t\t\t\tnew PrimitiveSerializer(typeof (sbyte)),\n\t\t\t\tnew PrimitiveSerializer(typeof (float)),\n\t\t\t\tnew PrimitiveSerializer(typeof (ushort)),\n\t\t\t\tnew PrimitiveSerializer(typeof (uint)),\n\t\t\t\tnew PrimitiveSerializer(typeof (ulong)),\n\t\t\t\tnew PrimitiveSerializer(typeof (string)),\n\t\t\t};\n\t\t}\n\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream jsonOutput)\n\t\t{\n\t\t\tSerialize(objectToSerialize, jsonOutput, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream jsonOutput, Encoding encoding)\n\t\t{\n\t\t\tSerialize(objectToSerialize, jsonOutput, CreateDefaultContext(SerializationOptions.None, encoding));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream jsonOutput, SerializationOptions options)\n\t\t{\n\t\t\tSerialize(objectToSerialize, jsonOutput, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream jsonOutput, SerializationOptions options, Encoding encoding)\n\t\t{\n\t\t\tSerialize(objectToSerialize, jsonOutput, CreateDefaultContext(options, encoding));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream jsonOutput, SerializationContext context)\n\t\t{\n\t\t\tif (jsonOutput == null) throw new ArgumentNullException(\"jsonOutput\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (!jsonOutput.CanWrite) throw JsonSerializationException.StreamIsNotWriteable();\n\n\n\t\t\tif (objectToSerialize == null)\n\t\t\t{\n\t\t\t\tvar bytes = context.Encoding.GetBytes(\"null\");\n\t\t\t\tjsonOutput.Write(bytes, 0, bytes.Length);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar writer = new JsonStreamWriter(jsonOutput, context);\n\t\t\twriter.WriteValue(objectToSerialize, typeof(T));\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tpublic static void Serialize<T>(T objectToSerialize, TextWriter textWriter)\n\t\t{\n\t\t\tSerialize(objectToSerialize, textWriter, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, TextWriter textWriter, SerializationOptions options)\n\t\t{\n\t\t\tSerialize(objectToSerialize, textWriter, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, TextWriter textWriter, SerializationContext context)\n\t\t{\n\t\t\tif (textWriter == null) throw new ArgumentNullException(\"textWriter\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\t\t\tif (objectToSerialize == null)\n\t\t\t{\n\t\t\t\ttextWriter.Write(\"null\");\n\t\t\t\ttextWriter.Flush();\n\t\t\t\treturn;\n\t\t\t}\n\n\n\t\t\tvar writer = new JsonTextWriter(textWriter, context);\n\t\t\twriter.WriteValue(objectToSerialize, typeof(T));\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tpublic static void Serialize<T>(T objectToSerialize, IJsonWriter writer, SerializationContext context)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\t\t\tif (objectToSerialize == null)\n\t\t\t{\n\t\t\t\twriter.WriteNull();\n\t\t\t\twriter.Flush();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twriter.WriteValue(objectToSerialize, typeof(T));\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tpublic static string SerializeToString<T>(T objectToSerialize)\n\t\t{\n\t\t\treturn SerializeToString(objectToSerialize, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static string SerializeToString<T>(T objectToSerialize, SerializationOptions options)\n\t\t{\n\t\t\treturn SerializeToString(objectToSerialize, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static string SerializeToString<T>(T objectToSerialize, SerializationContext context)\n\t\t{\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\t\t\tif (objectToSerialize == null)\n\t\t\t\treturn \"null\";\n\n\t\t\tvar writer = new JsonStringBuilderWriter(new StringBuilder(), context);\n\t\t\twriter.WriteValue(objectToSerialize, typeof(T));\n\t\t\twriter.Flush();\n\n\t\t\treturn writer.ToString();\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, byte[] jsonBytes, int offset, int length)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(jsonBytes, offset, length));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, byte[] jsonBytes, int offset, int length, Encoding encoding)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(jsonBytes, offset, length), encoding);\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, byte[] jsonBytes, int offset, int length, SerializationOptions options)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(jsonBytes, offset, length), options);\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, byte[] jsonBytes, int offset, int length, SerializationOptions options, Encoding encoding)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(jsonBytes, offset, length), options, encoding);\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, byte[] jsonBytes, int offset, int length, SerializationContext context)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(jsonBytes, offset, length), context);\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, Stream jsonStream)\n\t\t{\n\t\t\treturn Deserialize(objectType, jsonStream, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, Stream jsonStream, Encoding encoding)\n\t\t{\n\t\t\treturn Deserialize(objectType, jsonStream, CreateDefaultContext(SerializationOptions.None, encoding));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, Stream jsonStream, SerializationOptions options)\n\t\t{\n\t\t\treturn Deserialize(objectType, jsonStream, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, Stream jsonStream, SerializationOptions options, Encoding encoding)\n\t\t{\n\t\t\treturn Deserialize(objectType, jsonStream, CreateDefaultContext(options, encoding));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, Stream jsonStream, SerializationContext context)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\t\t\tif (jsonStream == null) throw new ArgumentNullException(\"jsonStream\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (!jsonStream.CanRead) throw JsonSerializationException.StreamIsNotReadable();\n\n\t\t\tvar reader = new JsonStreamReader(jsonStream, context);\n\t\t\treturn reader.ReadValue(objectType, false);\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, TextReader textReader)\n\t\t{\n\t\t\treturn Deserialize(objectType, textReader, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, TextReader textReader, SerializationOptions options)\n\t\t{\n\t\t\treturn Deserialize(objectType, textReader, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, TextReader textReader, SerializationContext context)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\t\t\tif (textReader == null) throw new ArgumentNullException(\"textReader\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\t\t\tvar reader = new JsonTextReader(textReader, context);\n\t\t\treturn reader.ReadValue(objectType, false);\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, string jsonString)\n\t\t{\n\t\t\treturn Deserialize(objectType, jsonString, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, string jsonString, SerializationOptions options)\n\t\t{\n\t\t\treturn Deserialize(objectType, jsonString, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, string jsonString, SerializationContext context)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\t\t\tif (jsonString == null) throw new ArgumentNullException(\"jsonString\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\n\t\t\tvar reader = new JsonStringReader(jsonString, context);\n\t\t\treturn reader.ReadValue(objectType, false);\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, IJsonReader reader)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\treturn reader.ReadValue(objectType, false);\n\t\t}\n\n\n\t\tpublic static T Deserialize<T>(byte[] jsonBytes, int offset, int length)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(jsonBytes, offset, length));\n\t\t}\n\t\tpublic static T Deserialize<T>(byte[] jsonBytes, int offset, int length, Encoding encoding)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(jsonBytes, offset, length), encoding);\n\t\t}\n\t\tpublic static T Deserialize<T>(byte[] jsonBytes, int offset, int length, SerializationOptions options)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(jsonBytes, offset, length), options);\n\t\t}\n\t\tpublic static T Deserialize<T>(byte[] jsonBytes, int offset, int length, SerializationOptions options, Encoding encoding)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(jsonBytes, offset, length), options, encoding);\n\t\t}\n\t\tpublic static T Deserialize<T>(byte[] jsonBytes, int offset, int length, SerializationContext context)\n\t\t{\n\t\t\tif (jsonBytes == null) throw new ArgumentNullException(\"jsonBytes\");\n\n\t\t\treturn Deserialize<T>( new MemoryStream(jsonBytes, offset, length), context);\n\t\t}\n\n\n\t\tpublic static T Deserialize<T>(Stream jsonStream)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonStream, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static T Deserialize<T>(Stream jsonStream, Encoding encoding)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonStream, CreateDefaultContext(SerializationOptions.None, encoding));\n\t\t}\n\t\tpublic static T Deserialize<T>(Stream jsonStream, SerializationOptions options)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonStream, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static T Deserialize<T>(Stream jsonStream, SerializationOptions options, Encoding encoding)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonStream, CreateDefaultContext(options, encoding));\n\t\t}\n\t\tpublic static T Deserialize<T>(Stream jsonStream, SerializationContext context)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonStream, context);\n\n\t\t}\n\n\t\tpublic static T Deserialize<T>(TextReader textReader)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), textReader, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static T Deserialize<T>(TextReader textReader, SerializationOptions options)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), textReader, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static T Deserialize<T>(TextReader textReader, SerializationContext context)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), textReader, context);\n\t\t}\n\n\t\tpublic static T Deserialize<T>(string jsonString)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonString, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static T Deserialize<T>(string jsonString, SerializationOptions options)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonString, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static T Deserialize<T>(string jsonString, SerializationContext context)\n\t\t{\n\t\t\treturn (T)Deserialize(typeof(T), jsonString, context);\n\t\t}\n\n\t\tpublic static T Deserialize<T>(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tvar serializer = reader.Context.GetSerializerForType(typeof(T));\n\t\t\treturn (T)serializer.Deserialize(reader);\n\t\t}\n\n\t\tprivate static SerializationContext CreateDefaultContext(SerializationOptions options, Encoding encoding = null)\n\t\t{\n\t\t\treturn new SerializationContext\n\t\t\t{\n\t\t\t\tEncoding = encoding ?? DefaultEncoding,\n\t\t\t\tOptions = options\n\t\t\t};\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Json.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: ae711c9fe19244fab91b2218cc02ae50\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonMember.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Linq;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic struct JsonMember : IEquatable<JsonMember>, IEquatable<string>\n\t{\n\t\tinternal string NameString;\n\t\tinternal char[] NameChars;\n\t\tinternal bool IsEscapedAndQuoted;\n\n\t\tpublic int Length\n\t\t{\n\t\t\tget { return this.NameString != null ? this.NameString.Length : this.NameChars.Length; }\n\t\t}\n\n\t\tpublic JsonMember(string name)\n\t\t\t: this(name, false)\n\t\t{\n\t\t}\n\n\t\tpublic JsonMember(string name, bool escapedAndQuoted)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(\"name\");\n\n\t\t\tthis.NameString = name;\n\t\t\tthis.IsEscapedAndQuoted = escapedAndQuoted;\n\t\t\tthis.NameChars = null;\n\t\t}\n\n\t\tpublic JsonMember(char[] name)\n\t\t\t: this(name, false)\n\t\t{\n\t\t}\n\n\t\tpublic JsonMember(char[] name, bool escapedAndQuoted)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(\"name\");\n\n\t\t\tthis.NameChars = name;\n\t\t\tthis.IsEscapedAndQuoted = escapedAndQuoted;\n\t\t\tthis.NameString = null;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn this.NameString != null ? this.NameString.GetHashCode() : this.NameChars.Aggregate(0, (a, c) => a ^ (int) c);\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is JsonMember)\n\t\t\t\treturn this.Equals((JsonMember) obj);\n\t\t\telse if (obj is string)\n\t\t\t\treturn this.Equals((string) obj);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool Equals(JsonMember other)\n\t\t{\n\t\t\treturn this.ToString().Equals(other.ToString(), StringComparison.Ordinal);\n\t\t}\n\n\t\tpublic bool Equals(string other)\n\t\t{\n\t\t\treturn this.ToString().Equals(other, StringComparison.Ordinal);\n\t\t}\n\n\t\tpublic static explicit operator string(JsonMember member)\n\t\t{\n\t\t\treturn member.ToString();\n\t\t}\n\n\t\tpublic static explicit operator JsonMember(string memberName)\n\t\t{\n\t\t\treturn new JsonMember(memberName);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tvar name = NameString;\n\t\t\tif (this.NameChars != null)\n\t\t\t\tname = new string(NameChars, 0, NameChars.Length);\n\n\t\t\t// this is used in tests, so perf is not primary\n\t\t\tif (this.IsEscapedAndQuoted)\n\t\t\t{\n\t\t\t\tif (name.EndsWith(\":\"))\n\t\t\t\t\tname = name.Substring(0, name.Length - 1);\n\n\t\t\t\tname = JsonUtils.UnescapeAndUnquote(name);\n\t\t\t}\n\n\t\t\treturn name;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonMember.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: d9e3f4d0576d4f3d9e6f9e93a0833f07\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonReader.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Globalization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic abstract class JsonReader : IJsonReader\n\t{\n\t\tprotected const int DEFAULT_BUFFER_SIZE = 1024;\n\n\t\tprivate sealed class Buffer : IList<char>\n\t\t{\n\t\t\tprivate const float SHIFT_THRESHOLD = 0.5f; // position over 50% of buffer\n\t\t\tprivate const float GROW_THRESHOLD = 0.1f; // when less that 10% of space is free\n\n\t\t\tprivate readonly JsonReader reader;\n\t\t\tprivate char[] buffer;\n\t\t\tprivate int? lazyFixation;\n\t\t\tprivate int end;\n\t\t\tprivate readonly int initialSize;\n\t\t\tprivate bool isLast;\n\t\t\tprivate int lineNumber;\n\t\t\tprivate long lineStartIndex;\n\t\t\tprivate long charsReaded;\n\n\t\t\tprivate int Capacity\n\t\t\t{\n\t\t\t\tget { return this.buffer.Length; }\n\t\t\t\tset\n\t\t\t\t{\n\t\t\t\t\tif (value <= 0)\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(\"value\");\n\n\t\t\t\t\tvar newBuffer = new char[value];\n\t\t\t\t\tBlockCopy(this.buffer, 0, newBuffer, 0, Math.Min(newBuffer.Length, this.buffer.Length));\n\t\t\t\t\tthis.buffer = newBuffer;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int Offset { get; private set; }\n\t\t\tpublic long CharactersReaded { get { return this.charsReaded + this.Offset; } }\n\t\t\tpublic int LineNumber { get { return this.lineNumber + 1; } }\n\t\t\tpublic int ColumnNumber { get { return (int)(this.CharactersReaded - this.lineStartIndex + 1); } }\n\t\t\tpublic char this[int index]\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tif (index < 0)\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(\"index\");\n\n\t\t\t\t\tif (this.IsBeyondOfStream(index))\n\t\t\t\t\t\treturn (char)0;\n\n\t\t\t\t\treturn this.buffer[this.Offset + index];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic Buffer(JsonReader reader, char[] buffer)\n\t\t\t{\n\t\t\t\tif (reader == null) new ArgumentNullException(\"reader\");\n\n\t\t\t\tthis.reader = reader;\n\t\t\t\tthis.buffer = buffer ?? new char[DEFAULT_BUFFER_SIZE];\n\t\t\t\tthis.initialSize = this.buffer.Length;\n\t\t\t\tthis.end = 0;\n\t\t\t\tthis.Offset = 0;\n\t\t\t}\n\n\t\t\tpublic void FixateNow()\n\t\t\t{\n\t\t\t\tif (this.lazyFixation == null) return;\n\n\t\t\t\tthis.Fixate(this.lazyFixation.Value);\n\t\t\t\tthis.lazyFixation = null;\n\t\t\t}\n\t\t\tpublic void Fixate(int atIndex)\n\t\t\t{\n\t\t\t\tif (atIndex < 0) throw new ArgumentOutOfRangeException(\"atIndex\");\n\n\t\t\t\tfor (var i = 0; i < atIndex; i++)\n\t\t\t\t{\n\t\t\t\t\tif (this[i] != '\\n') continue;\n\n\t\t\t\t\tthis.lineNumber++;\n\t\t\t\t\tthis.lineStartIndex = this.CharactersReaded + i;\n\t\t\t\t}\n\n\t\t\t\t// ensure that fixation point in loaded range\n\t\t\t\tthis.IsBeyondOfStream(atIndex);\n\n\t\t\t\tthis.Offset += atIndex;\n\n\t\t\t\t// when we are at second half of buffer - we need to shift back\n\t\t\t\tif ((this.Offset / (float)this.buffer.Length) > SHIFT_THRESHOLD)\n\t\t\t\t\tthis.ShiftToZero();\n\t\t\t}\n\t\t\tpublic void FixateLater(int atIndex)\n\t\t\t{\n\t\t\t\tif (atIndex < 0) throw new ArgumentOutOfRangeException(\"atIndex\");\n\n\t\t\t\tif (this.lazyFixation != null)\n\t\t\t\t\tthis.lazyFixation += atIndex;\n\t\t\t\telse\n\t\t\t\t\tthis.lazyFixation = atIndex;\n\t\t\t}\n\n\t\t\tpublic bool IsBeyondOfStream(int index)\n\t\t\t{\n\t\t\t\tif (!this.isLast && this.Offset + index >= this.end)\n\t\t\t\t\tthis.ReadNextBlock();\n\n\t\t\t\tif (this.isLast && this.Offset + index >= this.end)\n\t\t\t\t\treturn true;\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tpublic char[] GetChars()\n\t\t\t{\n\t\t\t\treturn this.buffer;\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthis.FixateNow();\n\t\t\t\tthis.ShiftToZero();\n\t\t\t\tthis.charsReaded = 0;\n\t\t\t\tthis.lineNumber = 0;\n\t\t\t\tthis.lineStartIndex = 0;\n\t\t\t}\n\n\t\t\tprivate void ReadNextBlock()\n\t\t\t{\n\t\t\t\t// when we are at second half of buffer - we need to shift back\n\t\t\t\tif ((this.Offset / (float)this.buffer.Length) > SHIFT_THRESHOLD)\n\t\t\t\t\tthis.ShiftToZero();\n\n\t\t\t\t// check for free space\n\t\t\t\tvar free = this.buffer.Length - this.end;\n\t\t\t\tif ((free / (float)this.initialSize) < GROW_THRESHOLD)\n\t\t\t\t\tthis.Capacity += this.initialSize;\n\n\t\t\t\tvar newEnd = this.reader.FillBuffer(this.buffer, this.end);\n\t\t\t\tthis.isLast = newEnd == this.end;\n\t\t\t\tthis.end = newEnd;\n\t\t\t}\n\n\t\t\tprivate void ShiftToZero()\n\t\t\t{\n\t\t\t\tthis.charsReaded += this.Offset;\n\n\t\t\t\tvar block = Math.Min(this.Offset, this.end - this.Offset);\n\t\t\t\tvar start = this.Offset;\n\t\t\t\tvar lastBlock = 0;\n\t\t\t\twhile (start < this.end)\n\t\t\t\t{\n\t\t\t\t\tBlockCopy(this.buffer, start, this.buffer, lastBlock, Math.Min(block, this.end - start));\n\t\t\t\t\tlastBlock += block;\n\t\t\t\t\tstart += block;\n\t\t\t\t}\n\n\t\t\t\tthis.end = this.end - this.Offset;\n\t\t\t\tthis.Offset = 0;\n#if DEBUG\n\t\t\t\tif (this.end < this.buffer.Length) // zero unused space(just for debug)\n\t\t\t\t\tArray.Clear(this.buffer, this.end, this.buffer.Length - this.end);\n#endif\n\t\t\t}\n\n\t\t\tprivate static void BlockCopy(char[] from, int fromIdx, char[] to, int toIdx, int len)\n\t\t\t{\n\t\t\t\tconst int CHAR_SIZE = sizeof(char);\n\n\t\t\t\tSystem.Buffer.BlockCopy(from, fromIdx * CHAR_SIZE, to, toIdx * CHAR_SIZE, len * CHAR_SIZE);\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn new string(this.buffer, this.Offset, this.end - this.Offset);\n\t\t\t}\n\n\t\t\t#region IList<char> Members\n\n\t\t\tint IList<char>.IndexOf(char item)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tvoid IList<char>.Insert(int index, char item)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tvoid IList<char>.RemoveAt(int index)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tchar IList<char>.this[int index]\n\t\t\t{\n\t\t\t\tget { return this[index]; }\n\t\t\t\tset { throw new NotImplementedException(); }\n\t\t\t}\n\n\t\t\t#endregion\n\n\t\t\t#region ICollection<char> Members\n\n\t\t\tvoid ICollection<char>.Add(char item)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tvoid ICollection<char>.Clear()\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tbool ICollection<char>.Contains(char item)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tvoid ICollection<char>.CopyTo(char[] array, int arrayIndex)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tint ICollection<char>.Count\n\t\t\t{\n\t\t\t\tget { return this.buffer.Length; }\n\t\t\t}\n\n\t\t\tbool ICollection<char>.IsReadOnly\n\t\t\t{\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tbool ICollection<char>.Remove(char item)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\t#endregion\n\n\t\t\t#region IEnumerable<char> Members\n\n\t\t\tIEnumerator<char> IEnumerable<char>.GetEnumerator()\n\t\t\t{\n\t\t\t\treturn (this.buffer as IList<char>).GetEnumerator();\n\t\t\t}\n\n\t\t\t#endregion\n\n\t\t\t#region IEnumerable Members\n\n\t\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this.buffer.GetEnumerator();\n\t\t\t}\n\n\t\t\t#endregion\n\t\t}\n\n\t\tprivate sealed class LazyValueInfo : IValueInfo\n\t\t{\n\t\t\tprivate enum Kind : byte\n\t\t\t{\n\t\t\t\tExplicit = 0,\n\t\t\t\tQuotedString,\n\t\t\t\tString\n\t\t\t};\n\n\t\t\tprivate readonly JsonReader reader;\n\t\t\tprivate int jsonStart;\n\t\t\tprivate int jsonLen;\n\t\t\tprivate object value;\n\t\t\tprivate Kind valueKind;\n\n\t\t\tpublic bool HasValue { get; private set; }\n\t\t\tpublic object Raw\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\t// eval lazy value\n\t\t\t\t\tif (this.valueKind == Kind.String)\n\t\t\t\t\t\tthis.Raw = new string(this.reader.buffer.GetChars(), this.reader.buffer.Offset + this.jsonStart, this.jsonLen);\n\t\t\t\t\telse if (this.valueKind == Kind.QuotedString)\n\t\t\t\t\t\tthis.Raw = JsonUtils.UnescapeBuffer(this.reader.buffer.GetChars(), this.reader.buffer.Offset + this.jsonStart, this.jsonLen);\n\n\t\t\t\t\treturn this.value;\n\t\t\t\t}\n\t\t\t\tset\n\t\t\t\t{\n\t\t\t\t\tthis.valueKind = Kind.Explicit;\n\t\t\t\t\tthis.value = value;\n\t\t\t\t\tthis.HasValue = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic Type Type\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tif (this.valueKind != Kind.Explicit)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (this.reader.token)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase JsonToken.BeginArray:\n\t\t\t\t\t\t\t\treturn typeof(List<object>);\n\t\t\t\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\t\t\t\treturn typeof(double);\n\t\t\t\t\t\t\tcase JsonToken.Member:\n\t\t\t\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\t\t\t\t\treturn typeof(string);\n\t\t\t\t\t\t\tcase JsonToken.DateTime:\n\t\t\t\t\t\t\t\treturn typeof(DateTime);\n\t\t\t\t\t\t\tcase JsonToken.Boolean:\n\t\t\t\t\t\t\t\treturn typeof(bool);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.value != null)\n\t\t\t\t\t\treturn this.value.GetType();\n\t\t\t\t\telse\n\t\t\t\t\t\treturn typeof(object);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic int LineNumber { get; private set; }\n\t\t\tpublic int ColumnNumber { get; private set; }\n\t\t\tpublic bool AsBoolean { get { return Convert.ToBoolean(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic byte AsByte { get { return Convert.ToByte(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic short AsInt16 { get { return Convert.ToInt16(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic int AsInt32 { get { return Convert.ToInt32(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic long AsInt64 { get { return Convert.ToInt64(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic sbyte AsSByte { get { return Convert.ToSByte(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic ushort AsUInt16 { get { return Convert.ToUInt16(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic uint AsUInt32 { get { return Convert.ToUInt32(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic ulong AsUInt64 { get { return Convert.ToUInt64(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic float AsSingle { get { return Convert.ToSingle(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic double AsDouble { get { return Convert.ToDouble(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic decimal AsDecimal { get { return Convert.ToDecimal(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic DateTime AsDateTime\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tif (this.Raw is DateTime) return (DateTime)this.Raw;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn DateTime.ParseExact(this.AsString, this.reader.Context.DateTimeFormats, this.reader.Context.Format,\n\t\t\t\t\t\t\tDateTimeStyles.AssumeUniversal);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic string AsString\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tvar raw = this.Raw;\n\t\t\t\t\tif (raw is string)\n\t\t\t\t\t\treturn (string)raw;\n\t\t\t\t\telse if (raw is byte[])\n\t\t\t\t\t\treturn Convert.ToBase64String((byte[])raw);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn Convert.ToString(raw, this.reader.Context.Format);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic LazyValueInfo(JsonReader reader)\n\t\t\t{\n\t\t\t\tif (reader == null)\n\t\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\t\t\t\tthis.reader = reader;\n\t\t\t}\n\n\t\t\tpublic void ClearValue()\n\t\t\t{\n\t\t\t\tthis.value = null;\n\t\t\t\tthis.HasValue = false;\n\t\t\t\tthis.valueKind = Kind.String;\n\t\t\t}\n\n\t\t\tpublic void SetBufferBounds(int start, int len)\n\t\t\t{\n\t\t\t\tif (start < 0)\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\t\tif (len < 0)\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\n\t\t\t\tthis.LineNumber = this.reader.buffer.LineNumber;\n\t\t\t\tthis.ColumnNumber = this.reader.buffer.ColumnNumber + start;\n\t\t\t\tthis.jsonStart = start;\n\t\t\t\tthis.jsonLen = len;\n\t\t\t}\n\t\t\tpublic void SetAsLazyString(bool quoted)\n\t\t\t{\n\t\t\t\tthis.valueKind = quoted ? Kind.QuotedString : Kind.String;\n\t\t\t\tthis.HasValue = true;\n\t\t\t}\n\t\t}\n\n\t\tprivate const char INSIGNIFICANT_TAB = '\\t';\n\t\tprivate const char INSIGNIFICANT_SPACE = ' ';\n\t\tprivate const char INSIGNIFICANT_NEWLINE = '\\n';\n\t\tprivate const char INSIGNIFICANT_RETURN = '\\r';\n\t\tprivate const char INSIGNIFICANT_NAME_SEPARATOR = ':';\n\t\tprivate const char INSIGNIFICANT_VALUE_SEPARATOR = ',';\n\t\tprivate const char SIGNIFICANT_BEGIN_ARRAY = '[';\n\t\tprivate const char SIGNIFICANT_END_ARRAY = ']';\n\t\tprivate const char SIGNIFICANT_BEGIN_OBJECT = '{';\n\t\tprivate const char SIGNIFICANT_END_OBJECT = '}';\n\t\tprivate const char SIGNIFICANT_QUOTE = '\\\"';\n\t\tprivate const char SIGNIFICANT_QUOTE_ALT = '\\'';\n\n\t\tprivate LazyValueInfo lazyValue;\n\t\tprivate JsonToken token;\n\t\tprivate readonly Buffer buffer;\n\n\t\tprotected JsonReader(SerializationContext context, char[] buffer = null)\n\t\t{\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (buffer != null && buffer.Length < 1024) throw new ArgumentOutOfRangeException(\"buffer\", \"Buffer should be at least 1024 chars long.\");\n\n\t\t\tthis.Context = context;\n\t\t\tthis.lazyValue = new LazyValueInfo(this);\n\t\t\tthis.buffer = new Buffer(this, buffer);\n\t\t}\n\n\t\t#region IJsonReader Members\n\n\t\tpublic SerializationContext Context { get; private set; }\n\n\t\tpublic IValueInfo Value\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (this.Token == JsonToken.None)\n\t\t\t\t\tthis.NextToken();\n\t\t\t\treturn this.lazyValue;\n\t\t\t}\n\t\t}\n\n\t\tpublic JsonToken Token\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (this.token == JsonToken.None)\n\t\t\t\t\tthis.NextToken();\n\n\t\t\t\treturn this.token;\n\t\t\t}\n\t\t}\n\n\t\tpublic object RawValue\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (this.token == JsonToken.None)\n\t\t\t\t\tthis.NextToken();\n\n\t\t\t\treturn this.Value.Raw;\n\t\t\t}\n\t\t}\n\n\t\tpublic long CharactersReaded\n\t\t{\n\t\t\tget { return this.buffer.CharactersReaded; }\n\t\t}\n\n\t\tpublic bool NextToken()\n\t\t{\n\t\t\tvar start = 0;\n\t\t\tvar len = 0;\n\t\t\tvar quoted = false;\n\t\t\tvar isMember = false;\n\n\t\t\tif (!this.NextLexeme(ref start, ref len, ref quoted, ref isMember)) // end of stream\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.EndOfStream;\n\t\t\t\tthis.lazyValue.Raw = null;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.lazyValue.ClearValue();\n\t\t\tthis.lazyValue.SetBufferBounds(start, len);\n\t\t\tif (len == 1 && !quoted && this.buffer[start] == SIGNIFICANT_BEGIN_ARRAY)\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.BeginArray;\n\t\t\t}\n\t\t\telse if (len == 1 && !quoted && this.buffer[start] == SIGNIFICANT_BEGIN_OBJECT)\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.BeginObject;\n\t\t\t}\n\t\t\telse if (len == 1 && !quoted && this.buffer[start] == SIGNIFICANT_END_ARRAY)\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.EndOfArray;\n\t\t\t}\n\t\t\telse if (len == 1 && !quoted && this.buffer[start] == SIGNIFICANT_END_OBJECT)\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.EndOfObject;\n\t\t\t}\n\t\t\telse if (len == 4 && !quoted && this.LookupAt(this.buffer, start, len, \"null\"))\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.Null;\n\t\t\t}\n\t\t\telse if (len == 4 && !quoted && this.LookupAt(this.buffer, start, len, \"true\"))\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.Boolean;\n\t\t\t\tthis.lazyValue.Raw = true;\n\t\t\t}\n\t\t\telse if (len == 5 && !quoted && this.LookupAt(this.buffer, start, len, \"false\"))\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.Boolean;\n\t\t\t\tthis.lazyValue.Raw = false;\n\t\t\t}\n\t\t\telse if (quoted && this.LookupAt(this.buffer, start, 6, \"/Date(\") && this.LookupAt(this.buffer, start + len - 2, 2, \")/\"))\n\t\t\t{\n\t\t\t\tvar ticks = JsonUtils.StringToInt64(this.buffer.GetChars(), this.buffer.Offset + start + 6, len - 8);\n\n\t\t\t\tthis.token = JsonToken.DateTime;\n\t\t\t\tvar dateTime = new DateTime(ticks * 0x2710L + JsonUtils.UnixEpochTicks, DateTimeKind.Utc);\n\t\t\t\tthis.lazyValue.Raw = dateTime;\n\t\t\t}\n\t\t\telse if (!quoted && IsNumber(this.buffer, start, len))\n\t\t\t{\n\t\t\t\tthis.token = JsonToken.Number;\n\t\t\t\tthis.lazyValue.SetAsLazyString(false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.token = isMember ? JsonToken.Member : JsonToken.StringLiteral;\n\t\t\t\tthis.lazyValue.SetAsLazyString(quoted);\n\t\t\t}\n\n\t\t\tthis.buffer.FixateLater(start + len + (quoted ? 1 : 0));\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic bool IsEndOfStream()\n\t\t{\n\t\t\treturn this.token == JsonToken.EndOfStream;\n\t\t}\n\n\t\tpublic void Reset()\n\t\t{\n\t\t\tthis.buffer.Reset();\n\t\t\tif (this.token != JsonToken.EndOfStream)\n\t\t\t{\n\t\t\t\tthis.lazyValue = new LazyValueInfo(this);\n\t\t\t\tthis.token = JsonToken.None;\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\tprivate static bool IsNumber(Buffer buffer, int start, int len)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\n\n\t\t\tconst int INT_PART = 0;\n\t\t\tconst int FRAC_PART = 1;\n\t\t\tconst int EXP_PART = 2;\n\t\t\tconst char POINT = '.';\n\t\t\tconst char EXP = 'E';\n\t\t\tconst char PLUS = '+';\n\t\t\tconst char MINUS = '-';\n\n\t\t\tlen = start + len;\n\n\t\t\tvar part = INT_PART;\n\n\t\t\tfor (var i = start; i < len; i++)\n\t\t\t{\n\t\t\t\tvar ch = buffer[i];\n\n\t\t\t\tswitch (part)\n\t\t\t\t{\n\t\t\t\t\tcase INT_PART:\n\t\t\t\t\t\tif (ch == MINUS)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i != start)\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n#if !STRICT\n\t\t\t\t\t\telse if (ch == PLUS)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i != start)\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n#endif\n\t\t\t\t\t\telse if (ch == POINT)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i == start)\n\t\t\t\t\t\t\t\treturn false; // decimal point as first character\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tpart = FRAC_PART;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (char.ToUpper(ch) == EXP)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i == start)\n\t\t\t\t\t\t\t\treturn false; // exp at first character\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tpart = EXP_PART;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (!char.IsDigit(ch))\n\t\t\t\t\t\t\treturn false; // non digit character in int part\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase FRAC_PART:\n\t\t\t\t\t\tif (char.ToUpper(ch) == EXP)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i == start)\n\t\t\t\t\t\t\t\treturn false; // exp at first character\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tpart = EXP_PART;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (!char.IsDigit(ch))\n\t\t\t\t\t\t\treturn false; // non digit character in frac part\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EXP_PART:\n\t\t\t\t\t\tif ((ch == PLUS || ch == MINUS))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (char.ToUpper(buffer[i - 1]) != EXP)\n\t\t\t\t\t\t\t\treturn false; // sign not at start of exp part\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (!char.IsDigit(ch))\n\t\t\t\t\t\t\treturn false; // non digit character in exp part\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tprivate static bool IsInsignificantWhitespace(char symbol)\n\t\t{\n\t\t\treturn symbol == INSIGNIFICANT_NEWLINE || symbol == INSIGNIFICANT_RETURN || symbol == INSIGNIFICANT_SPACE ||\n\t\t\t\t   symbol == INSIGNIFICANT_TAB;\n\t\t}\n\t\tprivate static bool IsInsignificant(char symbol)\n\t\t{\n\t\t\treturn symbol == INSIGNIFICANT_NEWLINE || symbol == INSIGNIFICANT_RETURN || symbol == INSIGNIFICANT_SPACE ||\n\t\t\t\t   symbol == INSIGNIFICANT_TAB || symbol == INSIGNIFICANT_NAME_SEPARATOR || symbol == INSIGNIFICANT_VALUE_SEPARATOR;\n\t\t}\n\t\tprivate static bool IsLiteralTerminator(char ch, bool quoted, char quoteCh, bool escaped, bool eos, IJsonReader reader)\n\t\t{\n\t\t\tif (!escaped && quoted && ch == quoteCh)\n\t\t\t\treturn true;\n\t\t\telse if (quoted && (ch == INSIGNIFICANT_NEWLINE || ch == INSIGNIFICANT_RETURN))\n\t\t\t\tthrow JsonSerializationException.UnterminatedStringLiteral(reader);\n\t\t\telse if (eos)\n\t\t\t{\n\t\t\t\tif (quoted)\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedEndOfStream(reader);\n\t\t\t\telse\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (!quoted &&\n\t\t\t\t\t (ch == SIGNIFICANT_BEGIN_ARRAY || ch == SIGNIFICANT_BEGIN_OBJECT || ch == SIGNIFICANT_END_ARRAY ||\n\t\t\t\t\t  ch == SIGNIFICANT_END_OBJECT || ch == INSIGNIFICANT_VALUE_SEPARATOR || ch == INSIGNIFICANT_NAME_SEPARATOR))\n\t\t\t\treturn true;\n\t\t\telse if (!quoted && IsInsignificantWhitespace(ch))\n\t\t\t\treturn true;\n\n\t\t\treturn false;\n\t\t}\n\t\tprivate bool LookupAt(Buffer buffer, int start, int len, string matchString)\n\t\t{\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tif (buffer[start + i] != matchString[i])\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tprivate bool LookupAtSkipWhitespace(Buffer buffer, int start, int len, string matchString)\n\t\t{\n\t\t\twhile (IsInsignificantWhitespace(buffer[start])) start++;\n\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tif (buffer[start + i] != matchString[i])\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Get next lexeme from current buffer\n\t\t/// </summary>\n\t\t/// <param name=\"start\">return position of returned lexeme in buffer</param>\n\t\t/// <param name=\"len\">return size of returned lexeme</param>\n\t\t/// <param name=\"quoted\">return true when string literal was quoted</param>\n\t\t/// <param name=\"isMember\">is lexeme is object's member</param>\n\t\t/// <returns>Null in case of \"end of stream\", or character buffer with result</returns>\n\t\tprivate bool NextLexeme(ref int start, ref int len, ref bool quoted, ref bool isMember)\n\t\t{\n\t\t\t// apply 'lazy' fixation\n\t\t\tthis.buffer.FixateNow();\n\n\t\t\tif (this.buffer.IsBeyondOfStream(0))\n\t\t\t\treturn false;\n\n\t\t\tvar position = 0;\n\t\t\tvar ch = this.buffer[position];\n\n\t\t\t// skip insignificant characters\n\t\t\twhile (!this.buffer.IsBeyondOfStream(position) && IsInsignificant(this.buffer[position])) position++;\n\n\t\t\t// we reached end of stream\n\t\t\tif (this.buffer.IsBeyondOfStream(position))\n\t\t\t\treturn false;\n\n\n\t\t\t// tell buffer that significant characters starts here\n\t\t\t// this prevents buffer overgrow\n\t\t\tthis.buffer.Fixate(position);\n\t\t\tposition = 0;\n\t\t\tvar literalStart = position;\n\t\t\t//\n\n\t\t\tch = this.buffer[position];\n\t\t\t//\n\t\t\t// check for quote character\n\t\t\tvar quoteCh = '\\0';\n\t\t\tif (ch == SIGNIFICANT_QUOTE)\n\t\t\t{\n\t\t\t\tquoteCh = ch;\n\t\t\t\tquoted = true;\n\t\t\t\tposition++;\n\t\t\t\tliteralStart++;\n\t\t\t}\n#if !STRICT\n\t\t\telse if (ch == SIGNIFICANT_QUOTE_ALT)\n\t\t\t{\n\t\t\t\tquoteCh = ch;\n\t\t\t\tquoted = true;\n\t\t\t\tposition++;\n\t\t\t\tliteralStart++;\n\t\t\t}\n#endif\n\t\t\tvar escaped = false; // is character is escaped\n\t\t\tvar eos = false; // is end of stream\n\t\t\tdo\n\t\t\t{\n\t\t\t\teos = this.buffer.IsBeyondOfStream(position);\n\t\t\t\tescaped = ch == '\\\\';\n\t\t\t\tch = this.buffer[position];\n\t\t\t\tposition++;\n\t\t\t} while (!IsLiteralTerminator(ch, quoted, quoteCh, escaped, eos, this));\n\n\t\t\tvar literalEnd = position - 1; // minus terminator character\n\n\t\t\tstart = literalStart;\n\t\t\tlen = literalEnd - literalStart;\n\n\t\t\t// special case - self terminated lexeme\n\t\t\tif (literalStart == literalEnd && !quoted)\n\t\t\t\tlen = 1;\n\n\t\t\tisMember = this.LookupAtSkipWhitespace(this.buffer, literalEnd + (quoted ? 1 : 0), 1, \":\");\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Fills buffer with new characters, staring from <paramref name=\"index\" />\n\t\t/// </summary>\n\t\t/// <param name=\"buffer\">Character buffer to fill</param>\n\t\t/// <param name=\"index\">index from which to start</param>\n\t\t/// <returns>new buffer size</returns>\n\t\tprotected abstract int FillBuffer(char[] buffer, int index);\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 8ce453655ad14674adcc6bc3f730bf87\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonReaderExtentions.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Text;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic static class JsonReaderExtentions\n\t{\n\t\tpublic static void ReadArrayBegin(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tif (reader.Token != JsonToken.BeginArray)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.BeginArray);\n\t\t\tif (reader.IsEndOfStream())\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.EndOfArray);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\t\t}\n\t\tpublic static void ReadArrayEnd(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tif (reader.Token != JsonToken.EndOfArray)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.EndOfArray);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\t\t}\n\n\t\tpublic static void ReadObjectBegin(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tif (reader.Token != JsonToken.BeginObject)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.BeginObject);\n\t\t\tif (reader.IsEndOfStream())\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.EndOfObject);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\t\t}\n\t\tpublic static void ReadObjectEnd(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\t\t\tif (reader.Token != JsonToken.EndOfObject)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.EndOfObject);\n\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\t\t}\n\n\t\tpublic static string ReadMember(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tif (reader.Token != JsonToken.Member)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.Member);\n\n\t\t\tvar memberName = (string)reader.RawValue;\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn memberName;\n\t\t}\n\n\t\tpublic static byte ReadByte(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(byte);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsByte;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static byte? ReadByteOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(byte?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsByte;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static sbyte ReadSByte(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(sbyte);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsSByte;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static sbyte? ReadSByteOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(sbyte?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsSByte;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static short ReadInt16(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(short);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsInt16;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static short? ReadInt16OrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(short?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsInt16;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static int ReadInt32(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(int);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsInt32;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static int? ReadInt32OrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(int?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsInt32;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static long ReadInt64(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(long);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsInt64;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static long? ReadInt64OrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(long?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsInt64;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static ushort ReadUInt16(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(ushort);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsUInt16;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static ushort? ReadUInt16OrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(ushort?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsUInt16;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static uint ReadUInt32(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(uint);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsUInt32;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static uint? ReadUInt32OrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(uint?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsUInt32;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static ulong ReadUInt64(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(ulong);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsUInt64;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static ulong? ReadUInt64OrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(ulong?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsUInt64;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static float ReadSingle(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(float);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsSingle;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static float? ReadSingleOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(float?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsSingle;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static double ReadDouble(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(double);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsDouble;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static double? ReadDoubleOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(double?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsDouble;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static decimal ReadDecimal(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(decimal);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number)\n\t\t\t\tvalue = reader.Value.AsDecimal;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static decimal? ReadDecimalOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(decimal?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\tvalue = reader.Value.AsDecimal;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static bool ReadBoolean(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(bool);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Boolean)\n\t\t\t\tvalue = reader.Value.AsBoolean;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Boolean);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static bool? ReadBooleanOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(bool?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Boolean:\n\t\t\t\t\tvalue = reader.Value.AsBoolean;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Boolean);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static DateTime ReadDateTime(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(DateTime);\n\t\t\tif (reader.Token == JsonToken.Member || reader.Token == JsonToken.StringLiteral || reader.Token == JsonToken.Number || reader.Token == JsonToken.DateTime)\n\t\t\t\tvalue = reader.Value.AsDateTime;\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number, JsonToken.DateTime);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\t\tpublic static DateTime? ReadDateTimeOrNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tvar value = default(DateTime?);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tvalue = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\tcase JsonToken.DateTime:\n\t\t\t\t\tvalue = reader.Value.AsDateTime;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number, JsonToken.DateTime);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static string ReadString(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\t\t\tvar stringValue = default(string);\n\t\t\tswitch (reader.Token)\n\t\t\t{\n\t\t\t\tcase JsonToken.Null:\n\t\t\t\t\tbreak;\n\t\t\t\tcase JsonToken.Member:\n\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\tcase JsonToken.Number:\n\t\t\t\tcase JsonToken.DateTime:\n\t\t\t\tcase JsonToken.Boolean:\n\t\t\t\t\tstringValue = Convert.ToString(reader.RawValue, reader.Context.Format);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.StringLiteral, JsonToken.Number, JsonToken.DateTime, JsonToken.Boolean);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn stringValue;\n\t\t}\n\n\t\tpublic static void ReadNull(this IJsonReader reader, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token != JsonToken.Null)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.Null);\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\t\t}\n\n\t\tpublic static object ReadValue(this IJsonReader reader, Type valueType, bool nextToken = true)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\t// try guess type\n\t\t\tif (valueType == typeof(object))\n\t\t\t\tvalueType = reader.Value.Type;\n\n\t\t\tvar value = default(object);\n\t\t\tvar isNullable = valueType.IsValueType == false || valueType.IsInstantiationOf(typeof(Nullable<>));\n\t\t\tif (reader.Token == JsonToken.Null && isNullable)\n\t\t\t{\n\t\t\t\tvalue = null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (isNullable && valueType.IsValueType)\n\t\t\t\t\tvalueType = valueType.GetGenericArguments()[0]; // get subtype of Nullable<T>\n\n\t\t\t\tvar serializer = reader.Context.GetSerializerForType(valueType);\n\t\t\t\tvalue = serializer.Deserialize(reader);\n\t\t\t}\n\n\t\t\tif (nextToken)\n\t\t\t\treader.NextToken();\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static string DebugPrintTokens(this IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tvar output = new StringBuilder();\n\t\t\tvar stack = new Stack<JsonToken>();\n\t\t\tstack.Push(JsonToken.None);\n\t\t\twhile (reader.NextToken())\n\t\t\t{\n\t\t\t\tvar strValue = reader.Token + (reader.Value.HasValue && reader.Value != null ? \"[<\" + reader.Value.Type.Name + \"> \" + JsonUtils.EscapeAndQuote(reader.Value.AsString).Trim('\"') + \"]\" : \"\");\n\n\t\t\t\tif (stack.Peek() != JsonToken.Member)\n\t\t\t\t{\n\t\t\t\t\tvar endingTokenIndent = (reader.Token == JsonToken.EndOfObject || reader.Token == JsonToken.EndOfArray ? -1 : 0);\n\t\t\t\t\toutput.Append(Environment.NewLine);\n\t\t\t\t\tfor (var i = 0; i < System.Linq.Enumerable.Count(stack, t => t != JsonToken.Member && t != JsonToken.None) + endingTokenIndent; i++)\n\t\t\t\t\t\toutput.Append(\"\\t\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.Append(\" \");\n\t\t\t\t}\n\n\t\t\t\toutput.Append(strValue);\n\n\t\t\t\tif (reader.Token == JsonToken.EndOfObject || reader.Token == JsonToken.EndOfArray || stack.Peek() == JsonToken.Member)\n\t\t\t\t\tstack.Pop();\n\t\t\t\tif (reader.Token == JsonToken.BeginObject || reader.Token == JsonToken.BeginArray || reader.Token == JsonToken.Member)\n\t\t\t\t\tstack.Push(reader.Token);\n\t\t\t}\n\t\t\treturn output.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonReaderExtentions.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 91c78aa24ac24020bfde9485103e5a5b\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonSerializationException.cs",
    "content": "using System;\nusing System.Reflection;\nusing System.Runtime.Serialization;\nusing System.Security;\nusing GameDevWare.Serialization.Serializers;\n\n#pragma warning disable 1591\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\t[Serializable]\n\tpublic class JsonSerializationException : SerializationException\n\t{\n\t\tpublic enum ErrorCode\n\t\t{\n\t\t\tSerializationException = 1,\n\t\t\tEmptyMemberName,\n\t\t\tDiscriminatorNotFirstMemberOfObject,\n\t\t\tCantCreateInstanceOfType,\n\t\t\tSerializationGraphIsTooBig,\n\t\t\tSerializationGraphIsTooDeep,\n\t\t\tTypeIsNotValid,\n\t\t\tSerializingUnknownType,\n\t\t\tSerializingSpecialSystemType,\n\t\t\tUnexpectedEndOfStream,\n\t\t\tUnexpectedMemberName,\n\t\t\tUnexpectedToken,\n\t\t\tUnknownEscapeSequence,\n\t\t\tUnknownDiscriminatorValue,\n\t\t\tSerializationFramesCorruption,\n\t\t\tStreamIsNotReadable,\n\t\t\tStreamIsNotWriteable,\n\t\t\tUnterminatedStringLiteral,\n\t\t\tUnknownNotation,\n\t\t\tMemberNameIsNotSpecified,\n\t\t\tTypeRequiresCustomSerializer\n\t\t}\n\n\t\tpublic ErrorCode Code { get; set; }\n\t\tpublic int LineNumber { get; set; }\n\t\tpublic int ColumnNumber { get; set; }\n\t\tpublic ulong CharactersWritten { get; set; }\n\n\t\tinternal JsonSerializationException(string message, ErrorCode errorCode, IJsonReader reader = null)\n\t\t\t: base(message)\n\t\t{\n\t\t\tthis.Code = errorCode;\n\t\t\tif (reader != null)\n\t\t\t\tthis.Update(reader);\n\t\t}\n\t\tinternal JsonSerializationException(string message, ErrorCode errorCode, IJsonReader reader, Exception innerException)\n\t\t\t: base(message, innerException)\n\t\t{\n\t\t\tthis.Code = errorCode;\n\t\t\tif (reader != null)\n\t\t\t\tthis.Update(reader);\n\t\t}\n\t\tinternal JsonSerializationException(string message, Exception innerException)\n\t\t\t: base(message, innerException)\n\t\t{\n\t\t\tthis.Code = ErrorCode.SerializationException;\n\t\t}\n\n\t\tprotected JsonSerializationException(SerializationInfo info, StreamingContext context)\n\t\t\t: base(info, context)\n\t\t{\n\t\t\tthis.Code = (ErrorCode)info.GetInt32(\"Code\");\n\t\t\tthis.LineNumber = info.GetInt32(\"LineNumber\");\n\t\t\tthis.ColumnNumber = info.GetInt32(\"ColumnNumber\");\n\t\t\tthis.CharactersWritten = info.GetUInt64(\"CharactersWritten\");\n\t\t}\n\n\t\tprivate void Update(IJsonReader reader)\n\t\t{\n\t\t\tthis.LineNumber = reader.Value.LineNumber;\n\t\t\tthis.ColumnNumber = reader.Value.ColumnNumber;\n\t\t\t//this.Path = reader.Value.Path;\n\t\t}\n\n\t\t[SecurityCritical]\n\t\tpublic override void GetObjectData(SerializationInfo info, StreamingContext context)\n\t\t{\n\t\t\tinfo.AddValue(\"Code\", (int)this.Code);\n\t\t\tinfo.AddValue(\"LineNumber\", this.LineNumber);\n\t\t\tinfo.AddValue(\"ColumnNumber\", this.ColumnNumber);\n\t\t\tinfo.AddValue(\"CharactersWritten\", this.CharactersWritten);\n\n\t\t\tbase.GetObjectData(info, context);\n\t\t}\n\n\t\tpublic static Exception MemberNameIsEmpty(IJsonReader reader)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"An empty member name was deserialized. Path: '{0}'\", reader.Context.GetPath()),\n\t\t\t\tErrorCode.EmptyMemberName,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception MemberNameIsNotSet()\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\t\"A member name is not set before writing value to object.\",\n\t\t\t\tErrorCode.MemberNameIsNotSpecified\n\t\t\t);\n\t\t}\n\t\tpublic static Exception DiscriminatorIsNotFirstMember(IJsonReader reader)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Discriminator member '{0}' should be first member of object. Path: '{1}'.\", ObjectSerializer.TYPE_MEMBER_NAME, reader.Context.GetPath()),\n\t\t\t\tErrorCode.DiscriminatorNotFirstMemberOfObject,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception CantCreateInstanceOfType(Type type)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Unable to deserialize instance of '{0}' because \", type.FullName) +\n\t\t\t\t\t(type.GetTypeInfo().IsAbstract ? \"it is an abstract type.\" : \"there is no parameterless constructor is defined on type.\"),\n\t\t\t\tErrorCode.CantCreateInstanceOfType\n\t\t\t);\n\t\t}\n\t\tpublic static Exception SerializationGraphIsTooBig(IJsonReader reader, ulong maxObjects)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Serialization graph is too big. Maximum serialized objects is {0}. Path: '{1}'\", maxObjects, reader.Context.GetPath()),\n\t\t\t\tErrorCode.SerializationGraphIsTooBig\n\t\t\t);\n\t\t}\n\t\tpublic static Exception SerializationGraphIsTooDeep(IJsonReader reader, ulong maxDepth)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\t\tstring.Format(\"Serialization graph is too deep. Maximum depth is {0}. Path: '{1}'\", maxDepth, reader.Context.GetPath()),\n\t\t\t\tErrorCode.SerializationGraphIsTooDeep)\n\t\t\t;\n\t\t}\n\t\tpublic static Exception TypeIsNotValid(Type type, string problem)\n\t\t{\n\t\t\tproblem = problem.TrimEnd('.');\n\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Type '{0}' is not valid for serialization: {1}.\", type.Name, problem),\n\t\t\t\tErrorCode.TypeIsNotValid\n\t\t\t);\n\t\t}\n\t\tpublic static Exception SerializingUnknownType(Type type)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Attempt to serialize unknown type '{0}' failed.\", type.FullName),\n\t\t\t\tErrorCode.SerializingUnknownType\n\t\t\t);\n\t\t}\n\t\tpublic static Exception SerializingSpecialSystemType(Type type)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Attempt to serialize special system type '{0}' failed. This type is could be serialized.\", type.FullName),\n\t\t\t\tErrorCode.SerializingSpecialSystemType\n\t\t\t);\n\t\t}\n\t\tpublic static Exception UnexpectedEndOfStream(IJsonReader reader)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Unexpected end of stream while more data is expected. Path: '{0}'.\", reader.Context.GetPath()),\n\t\t\t\tErrorCode.UnexpectedEndOfStream,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception UnexpectedMemberName(string memberName, string expected, IJsonReader reader)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Unexpected member '{0}' is read while '{1}' is expected. Path: '{2}'.\", memberName, expected, reader.Context.GetPath()),\n\t\t\t\tErrorCode.UnexpectedMemberName,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception UnexpectedToken(IJsonReader reader, params JsonToken[] expectedTokens)\n\t\t{\n\t\t\tvar tokensStr = default(string);\n\t\t\tif (expectedTokens.Length == 0)\n\t\t\t{\n\t\t\t\ttokensStr = \"<no tokens>\";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n#if NET40\n\t\t\t\ttokensStr = String.Join(\", \", expectedTokens);\n#else\n\t\t\t\tvar tokens = expectedTokens.ConvertAll(c => c.ToString());\n\t\t\t\ttokensStr = String.Join(\", \", tokens);\n#endif\n\t\t\t}\n\n\t\t\tif (reader.Token == JsonToken.EndOfStream)\n\t\t\t{\n\t\t\t\treturn UnexpectedEndOfStream(reader);\n\t\t\t}\n\t\t\telse if (expectedTokens.Length > 1)\n\t\t\t{\n\t\t\t\treturn new JsonSerializationException\n\t\t\t\t(\n\t\t\t\t\tstring.Format(\"Unexpected token read '{0}' while any of '{1}' are expected. Path: '{2}'.\", reader.Token, tokensStr, reader.Context.GetPath()),\n\t\t\t\t\tErrorCode.UnexpectedToken,\n\t\t\t\t\treader\n\t\t\t\t);\n\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new JsonSerializationException\n\t\t\t\t(\n\t\t\t\t\tstring.Format(\"Unexpected token read '{0}' while '{1}' is expected. Path: '{2}'.\", reader.Token, tokensStr, reader.Context.GetPath()),\n\t\t\t\t\tErrorCode.UnexpectedToken,\n\t\t\t\t\treader\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tpublic static Exception UnknownEscapeSequence(string escape, IJsonReader reader)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"An unknown escape sequence '{0}' is read. Path: '{1}'.\", escape, reader.Context.GetPath()),\n\t\t\t\tErrorCode.UnknownEscapeSequence,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception SerializationFramesCorruption()\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\t\"Serialization frames are corrupted. Probably invalid Push/Pop sequence in TypeSerializers implementation.\",\n\t\t\t\tErrorCode.SerializationFramesCorruption\n\t\t\t);\n\t\t}\n\t\tpublic static Exception StreamIsNotReadable()\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\t\"Can\\'t perform deserialization from stream which doesn't support reading.\",\n\t\t\t\tErrorCode.StreamIsNotReadable\n\t\t\t);\n\t\t}\n\t\tpublic static Exception StreamIsNotWriteable()\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\t\"Can\\'t perform serialization to stream which doesn't support writing.\",\n\t\t\t\tErrorCode.StreamIsNotWriteable\n\t\t\t);\n\t\t}\n\t\tpublic static Exception UnterminatedStringLiteral(IJsonReader reader)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"An unterminated string literal. Path: '{0}'.\", reader.Context.GetPath()),\n\t\t\t\tErrorCode.UnterminatedStringLiteral,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception UnknownNotation(IJsonReader reader, string notation)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"An unknown notation '{0}'. Path: '{1}'.\", notation, reader.Context.GetPath()),\n\t\t\t\tErrorCode.UnknownNotation,\n\t\t\t\treader\n\t\t\t);\n\t\t}\n\t\tpublic static Exception TypeRequiresCustomSerializer(Type type, Type typeSerializer)\n\t\t{\n\t\t\treturn new JsonSerializationException\n\t\t\t(\n\t\t\t\tstring.Format(\"Type '{0}' can't be serialized by '{1}' and requires custom {2} registered in 'Json.DefaultSerializers'.\", type.FullName, typeSerializer.Name, typeof(TypeSerializer).Name),\n\t\t\t\tErrorCode.TypeRequiresCustomSerializer\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonSerializationException.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 9216e69600364fd8a766d27f04f18701\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStreamReader.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.IO;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonStreamReader : JsonReader\n\t{\n\t\tprivate readonly StreamReader reader;\n\n\t\tpublic JsonStreamReader(Stream stream, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (stream == null) throw new ArgumentNullException(\"stream\");\n\t\t\tif (!stream.CanRead) throw JsonSerializationException.StreamIsNotReadable();\n\n\t\t\tthis.reader = new StreamReader(stream, context.Encoding);\n\t\t}\n\n\t\tprotected override int FillBuffer(char[] buffer, int index)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (index < 0 || index >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"index\");\n\n\n\t\t\tvar count = buffer.Length - index;\n\t\t\tif (count <= 0)\n\t\t\t\treturn index;\n\n\t\t\tvar read = this.reader.Read(buffer, index, count);\n\t\t\treturn index + read;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStreamReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: dba4bb2b43a34afe956f2fe58a1d435d\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStreamWriter.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.IO;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonStreamWriter : JsonWriter\n\t{\n\t\tprivate readonly StreamWriter writer;\n\n\t\tpublic Stream Stream { get { return writer.BaseStream; } }\n\n\t\tpublic JsonStreamWriter(Stream stream, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (stream == null) throw new ArgumentNullException(\"stream\");\n\t\t\tif (!stream.CanWrite) throw JsonSerializationException.StreamIsNotWriteable();\n\n\n\t\t\twriter = new StreamWriter(stream, context.Encoding);\n\t\t}\n\n\t\tpublic override void Flush()\n\t\t{\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tpublic override void WriteJson(string jsonString)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\n\n\t\t\twriter.Write(jsonString);\n\t\t\tthis.CharactersWritten += jsonString.Length;\n\t\t}\n\n\t\tpublic override void WriteJson(char[] jsonString, int index, int charactersToWrite)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\t\t\tif (index < 0 || index >= jsonString.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"index\");\n\t\t\tif (charactersToWrite < 0 || index + charactersToWrite > jsonString.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"charactersToWrite\");\n\n\n\t\t\tif (charactersToWrite == 0)\n\t\t\t\treturn;\n\n\t\t\twriter.Write(jsonString, index, charactersToWrite);\n\t\t\tthis.CharactersWritten += charactersToWrite;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStreamWriter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: ea2e81bf26c44034887aeb8f01489170\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStringBuilderReader.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Text;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonStringBuilderReader : JsonReader\n\t{\n\t\tprivate readonly StringBuilder jsonString;\n\t\tprivate int position;\n\n\t\tpublic JsonStringBuilderReader(StringBuilder stringBuilder, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (stringBuilder == null)\n\t\t\t\tthrow new ArgumentNullException(\"str\");\n\n\n\t\t\tthis.jsonString = stringBuilder;\n\t\t\tthis.position = 0;\n\t\t}\n\n\t\tprotected override int FillBuffer(char[] buffer, int index)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (index < 0 || index >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"index\");\n\n\n\t\t\tvar block = Math.Min(this.jsonString.Length - position, buffer.Length - index);\n\t\t\tif (block <= 0)\n\t\t\t\treturn index;\n\n\t\t\tjsonString.CopyTo(position, buffer, index, block);\n\n\t\t\tposition += block;\n\n\t\t\treturn index + block;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStringBuilderReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: a7c8908a12104d4080e9a2979109faa3\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStringBuilderWriter.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Text;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonStringBuilderWriter : JsonWriter\n\t{\n\t\tprivate readonly StringBuilder stringBuilder;\n\n\t\tpublic StringBuilder Builder\n\t\t{\n\t\t\tget { return stringBuilder; }\n\t\t}\n\n\t\tpublic JsonStringBuilderWriter(StringBuilder stringBuilder, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (stringBuilder == null)\n\t\t\t\tthrow new ArgumentNullException(\"builder\");\n\n\n\t\t\tthis.stringBuilder = stringBuilder;\n\t\t}\n\n\n\t\tpublic override void Flush()\n\t\t{\n\t\t}\n\n\t\tpublic override void WriteJson(string jsonString)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\n\n\t\t\tstringBuilder.Append(jsonString);\n\t\t\tthis.CharactersWritten += jsonString.Length;\n\t\t}\n\n\t\tpublic override void WriteJson(char[] jsonString, int offset, int charactersToWrite)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\t\t\tif (offset < 0 || offset >= jsonString.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"offset\");\n\t\t\tif (charactersToWrite < 0 || offset + charactersToWrite > jsonString.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"charactersToWrite\");\n\n\n\t\t\tif (charactersToWrite == 0)\n\t\t\t\treturn;\n\n\t\t\tstringBuilder.Append(jsonString, offset, charactersToWrite);\n\t\t\tthis.CharactersWritten += charactersToWrite;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn stringBuilder.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStringBuilderWriter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: ba0b2700618d44678074988497f6811f\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStringReader.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonStringReader : JsonReader\n\t{\n\t\tprivate readonly string jsonString;\n\t\tprivate int position;\n\n\t\tpublic JsonStringReader(string jsonString, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\n\n\t\t\tthis.jsonString = jsonString;\n\t\t\tthis.position = 0;\n\t\t}\n\n\t\tprotected override int FillBuffer(char[] buffer, int index)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (index < 0 || index >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"index\");\n\n\n\t\t\tvar block = Math.Min(this.jsonString.Length - this.position, buffer.Length - index);\n\t\t\tif (block <= 0)\n\t\t\t\treturn index;\n\n\t\t\tthis.jsonString.CopyTo(this.position, buffer, index, block);\n\n\t\t\tthis.position += block;\n\n\t\t\treturn index + block;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonStringReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 87d7e0b24d7741298d295c21eb4bdb01\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonTextReader.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.IO;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonTextReader : JsonReader\n\t{\n\t\tprivate readonly TextReader reader;\n\n\t\tpublic JsonTextReader(TextReader reader, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t\tthrow new ArgumentNullException(\"reader\");\n\n\n\t\t\tthis.reader = reader;\n\t\t}\n\n\t\tprotected override int FillBuffer(char[] buffer, int index)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (index < 0 || index >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"index\");\n\n\n\t\t\tvar count = buffer.Length - index;\n\t\t\tif (count <= 0)\n\t\t\t\treturn index;\n\n\t\t\tvar read = this.reader.Read(buffer, index, count);\n\t\t\treturn index + read;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonTextReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 17d87f5a6e50464b9a12adaeaeaf64aa\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonTextWriter.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.IO;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class JsonTextWriter : JsonWriter\n\t{\n\t\tprivate readonly TextWriter writer;\n\n\t\tprivate TextWriter Writer\n\t\t{\n\t\t\tget { return writer; }\n\t\t}\n\n\t\tpublic JsonTextWriter(TextWriter writer, SerializationContext context, char[] buffer = null)\n\t\t\t: base(context, buffer)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tthis.writer = writer;\n\t\t}\n\n\t\tpublic override void Flush()\n\t\t{\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tpublic override void WriteJson(string jsonString)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\n\n\t\t\twriter.Write(jsonString);\n\t\t\tthis.CharactersWritten += jsonString.Length;\n\t\t}\n\n\t\tpublic override void WriteJson(char[] jsonString, int offset, int charactersToWrite)\n\t\t{\n\t\t\tif (jsonString == null)\n\t\t\t\tthrow new ArgumentNullException(\"jsonString\");\n\t\t\tif (offset < 0 || offset >= jsonString.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"offset\");\n\t\t\tif (charactersToWrite < 0 || offset + charactersToWrite > jsonString.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"charactersToWrite\");\n\n\n\t\t\tif (charactersToWrite == 0)\n\t\t\t\treturn;\n\n\t\t\twriter.Write(jsonString, offset, charactersToWrite);\n\t\t\tthis.CharactersWritten += charactersToWrite;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn writer.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonTextWriter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 68aac15450ed45c78a7b616ff202c96d\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonToken.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic enum JsonToken\n\t{\n\t\tNone = 0,\n\t\tBeginArray,\n\t\tEndOfArray,\n\t\tBeginObject,\n\t\tEndOfObject,\n\t\tMember,\n\t\tNumber,\n\t\tStringLiteral,\n\t\tDateTime,\n\t\tNull,\n\t\tBoolean,\n\t\tEndOfStream\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonToken.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: db426eb135514e37ab199c140e9de479\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonUtils.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Text;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tinternal static class JsonUtils\n\t{\n\t\tinternal static readonly long UnixEpochTicks = new DateTime(0x7b2, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;\n\n\t\tprivate static readonly char[] ZerBuff = new char[] {'0', '0', '0', '0', '0', '0', '0', '0',};\n\t\tprivate static readonly char[] HexChar = \"0123456789ABCDEF\".ToCharArray();\n\n\t\tpublic static string UnescapeAndUnquote(string stringToUnescape)\n\t\t{\n\t\t\tif (stringToUnescape == null)\n\t\t\t\tthrow new ArgumentNullException(\"stringToUnescape\");\n\n\n\t\t\tvar start = 0;\n\t\t\tvar len = stringToUnescape.Length;\n\n\t\t\tif (stringToUnescape.Length > 0 && stringToUnescape[0] == '\"')\n\t\t\t{\n\t\t\t\tstart += 1;\n\t\t\t\tlen -= 2;\n\t\t\t}\n\n\t\t\treturn UnescapeBuffer(stringToUnescape.ToCharArray(), start, len);\n\t\t}\n\n\t\tpublic static string EscapeAndQuote(string stringToEscape)\n\t\t{\n\t\t\tif (stringToEscape == null)\n\t\t\t\tthrow new ArgumentNullException(\"stringToEscape\");\n\n\n\t\t\tvar stringHasNonLatinCharacters = false;\n\t\t\tvar newSize = stringToEscape.Length + 2;\n\t\t\tfor (var i = 0; i < stringToEscape.Length; i++)\n\t\t\t{\n\t\t\t\tvar charToCheck = stringToEscape[i];\n\t\t\t\tvar isNonLatinOrSpecial = ((int) charToCheck < 32 || charToCheck == '\\\\' || charToCheck == '\"');\n\n\t\t\t\tif (isNonLatinOrSpecial)\n\t\t\t\t\tnewSize += 5; // encoded characters add 4 hex symbols and \"u\"\n\n\t\t\t\tstringHasNonLatinCharacters = stringHasNonLatinCharacters || isNonLatinOrSpecial;\n\t\t\t}\n\n\t\t\t// if it\"s a latin - write as is\n\t\t\tif (!stringHasNonLatinCharacters)\n\t\t\t\treturn string.Concat(\"\\\"\", stringToEscape, \"\\\"\");\n\n\t\t\t// else tranform and write\n\t\t\tvar sb = new StringBuilder(newSize);\n\t\t\tvar hexBuff = new char[12]; // 4 for zeroes and 8 for number\n\n\t\t\tsb.Append('\"');\n\t\t\tfor (var i = 0; i < stringToEscape.Length; i++)\n\t\t\t{\n\t\t\t\tvar charToCheck = stringToEscape[i];\n\n\t\t\t\tif ((int) charToCheck < 32 || charToCheck == '\\\\' || charToCheck == '\"')\n\t\t\t\t{\n\t\t\t\t\tsb.Append(\"\\\\u\");\n\t\t\t\t\tBuffer.BlockCopy(ZerBuff, 0, hexBuff, 0, sizeof (char)*8); // clear buffer with \"0\"\n\t\t\t\t\tvar hexlen = UInt32ToHexBuffer((uint) charToCheck, hexBuff, 4);\n\t\t\t\t\tsb.Append(hexBuff, hexlen, 4);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsb.Append(charToCheck);\n\t\t\t}\n\t\t\tsb.Append('\"');\n\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static int EscapeBuffer(string value, ref int offset, char[] outputBuffer, int outputBufferOffset)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t\tthrow new ArgumentNullException(\"value\");\n\t\t\tif (offset < 0 || offset >= value.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"offset\");\n\t\t\tif (outputBuffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"outputBuffer\");\n\t\t\tif (outputBufferOffset < 0 || outputBufferOffset >= outputBuffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"outputBufferOffset\");\n\n\n\t\t\tconst ushort LOWER_BOUND_CHAR = 32;\n\t\t\tconst ushort QUOTE_CHAR = '\\\\';\n\t\t\tconst ushort DOUBLE_QUOTE_CHAR = '\"';\n\n\t\t\tvar written = 0;\n\t\t\tfor (; offset < value.Length; offset++)\n\t\t\t{\n\t\t\t\tvar charCode = (ushort) value[offset];\n\t\t\t\tif (charCode < LOWER_BOUND_CHAR || charCode == QUOTE_CHAR || charCode == DOUBLE_QUOTE_CHAR)\n\t\t\t\t{\n\t\t\t\t\tif (outputBuffer.Length - outputBufferOffset < 6)\n\t\t\t\t\t\treturn written;\n\n\t\t\t\t\toutputBuffer[outputBufferOffset++] = '\\\\';\n\t\t\t\t\toutputBuffer[outputBufferOffset++] = 'u';\n\t\t\t\t\toutputBufferOffset += UInt16ToPaddedHexBuffer(charCode, outputBuffer, outputBufferOffset);\n\t\t\t\t\twritten += 6;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (outputBuffer.Length - outputBufferOffset == 0)\n\t\t\t\t\t\treturn written;\n\n\t\t\t\t\t// dont escape\n\t\t\t\t\toutputBuffer[outputBufferOffset++] = (char) charCode;\n\t\t\t\t\twritten++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn written;\n\t\t}\n\n\t\tpublic static string UnescapeBuffer(char[] charsToUnescape, int start, int length)\n\t\t{\n\t\t\tif (charsToUnescape == null)\n\t\t\t\tthrow new ArgumentNullException(\"charsToUnescape\");\n\t\t\tif (start < 0 || start + length > charsToUnescape.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tvar sb = new StringBuilder(length);\n\t\t\tvar plainStart = start;\n\t\t\tvar plainLen = 0;\n\t\t\tvar end = start + length;\n\t\t\tfor (var i = start; i < end; i++)\n\t\t\t{\n\t\t\t\tvar ch = charsToUnescape[i];\n\t\t\t\tif (ch == '\\\\')\n\t\t\t\t{\n\t\t\t\t\tvar seqLength = 1;\n\t\t\t\t\t// append unencoded chunk\n\t\t\t\t\tif (plainLen != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append(charsToUnescape, plainStart, plainLen);\n\t\t\t\t\t\tplainLen = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar seqKind = charsToUnescape[i + 1];\n\t\t\t\t\tswitch (seqKind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 'n':\n\t\t\t\t\t\t\tsb.Append('\\n');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'r':\n\t\t\t\t\t\t\tsb.Append('\\r');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'b':\n\t\t\t\t\t\t\tsb.Append('\\b');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'f':\n\t\t\t\t\t\t\tsb.Append('\\f');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 't':\n\t\t\t\t\t\t\tsb.Append('\\t');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\tsb.Append('\\\\');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\'':\n\t\t\t\t\t\t\tsb.Append('\\'');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\\"':\n\t\t\t\t\t\t\tsb.Append('\\\"');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// unicode symbol\n\t\t\t\t\t\tcase 'u':\n\t\t\t\t\t\t\tsb.Append((char) HexStringToUInt32(charsToUnescape, i + 2, 4));\n\t\t\t\t\t\t\tseqLength = 5;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// latin hex encoded symbol\n\t\t\t\t\t\tcase 'x':\n\t\t\t\t\t\t\tsb.Append((char) HexStringToUInt32(charsToUnescape, i + 2, 2));\n\t\t\t\t\t\t\tseqLength = 3;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// latin dec encoded symbol\n\t\t\t\t\t\tcase '1':\n\t\t\t\t\t\tcase '2':\n\t\t\t\t\t\tcase '3':\n\t\t\t\t\t\tcase '4':\n\t\t\t\t\t\tcase '5':\n\t\t\t\t\t\tcase '6':\n\t\t\t\t\t\tcase '7':\n\t\t\t\t\t\tcase '8':\n\t\t\t\t\t\tcase '9':\n\t\t\t\t\t\tcase '0':\n\t\t\t\t\t\t\tsb.Append((char) StringToInt32(charsToUnescape, i + 1, 3));\n\t\t\t\t\t\t\tseqLength = 3;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n#if STRICT\n                            throw new Exceptions.UnknownEscapeSequence(\"\\\\\" + seqKind.ToString(), null);\n#else\n\t\t\t\t\t\t\tsb.Append(charsToUnescape[i + 1]);\n\t\t\t\t\t\t\tbreak;\n#endif\n\t\t\t\t\t}\n\n\t\t\t\t\t// set next chunk start right after this escape\n\t\t\t\t\tplainStart = i + seqLength + 1;\n\t\t\t\t\ti += seqLength;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tplainLen++;\n\t\t\t}\n\n\t\t\t// append last unencoded chunk\n\t\t\tif (plainLen != 0)\n\t\t\t\tsb.Append(charsToUnescape, plainStart, plainLen);\n\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static uint HexStringToUInt32(char[] buffer, int start, int len)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\tconst uint ZERO = (ushort) '0';\n\t\t\tconst uint a = (ushort) 'a';\n\t\t\tconst uint A = (ushort) 'A';\n\n\t\t\tvar result = 0u;\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tvar c = buffer[start + i];\n\t\t\t\tvar d = 0u;\n\t\t\t\tif (c >= '0' && c <= '9')\n\t\t\t\t\td = (c - ZERO);\n\t\t\t\telse if (c >= 'a' && c <= 'f')\n\t\t\t\t\td = 10u + (c - a);\n\t\t\t\telse if (c >= 'A' && c <= 'F')\n\t\t\t\t\td = 10u + (c - A);\n\t\t\t\telse\n\t\t\t\t\tthrow new FormatException();\n\n\t\t\t\tresult = 16u*result + d;\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static int UInt32ToHexBuffer(uint uvalue, char[] buffer, int start)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tvar hex = HexChar;\n\n\t\t\tif (uvalue == 0)\n\t\t\t{\n\t\t\t\tbuffer[start] = '0';\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tvar length = 0;\n\t\t\tfor (var i = 0; i < 8; i++)\n\t\t\t{\n\t\t\t\tvar c = hex[((uvalue >> i*4) & 15u)];\n\t\t\t\tbuffer[start + i] = c;\n\t\t\t}\n\n\t\t\tfor (length = 8; length > 0; length--)\n\t\t\t\tif (buffer[start + length - 1] != '0')\n\t\t\t\t\tbreak;\n\n\t\t\tArray.Reverse(buffer, start, length);\n\n\t\t\treturn length;\n\t\t}\n\n\t\tpublic static int UInt16ToPaddedHexBuffer(ushort uvalue, char[] buffer, int start)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tconst int LENGTH = 4;\n\t\t\tconst string HEX = \"0123456789ABCDEF\";\n\n\t\t\tvar end = start + LENGTH;\n\t\t\tif (uvalue == 0)\n\t\t\t{\n\t\t\t\tfor (var i = start; i < end; i++)\n\t\t\t\t\tbuffer[i] = '0';\n\t\t\t\treturn LENGTH;\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < LENGTH; i++)\n\t\t\t{\n\t\t\t\tvar c = HEX[(int) ((uvalue >> i*4) & 15u)];\n\t\t\t\tbuffer[end - i - 1] = c;\n\t\t\t}\n\n\n\t\t\treturn LENGTH;\n\t\t}\n\n\t\tpublic static ushort PaddedHexStringToUInt16(char[] buffer, int start, int len)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\tconst uint ZERO = (ushort) '0';\n\t\t\tconst uint a = (ushort) 'a';\n\t\t\tconst uint A = (ushort) 'A';\n\n\t\t\tvar result = 0u;\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tvar c = buffer[start + i];\n\t\t\t\tvar d = 0u;\n\t\t\t\tif (c >= '0' && c <= '9')\n\t\t\t\t\td = (c - ZERO);\n\t\t\t\telse if (c >= 'a' && c <= 'f')\n\t\t\t\t\td = 10u + (c - a);\n\t\t\t\telse if (c >= 'A' && c <= 'F')\n\t\t\t\t\td = 10u + (c - A);\n\t\t\t\telse\n\t\t\t\t\tthrow new FormatException();\n\n\t\t\t\tresult = 16u*result + d;\n\t\t\t}\n\n\t\t\treturn checked((ushort) result);\n\t\t}\n\n\t\tpublic static long StringToInt64(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\tconst ulong ZERO = (ushort) '0';\n\n\t\t\tvar result = 0UL;\n\t\t\tvar neg = false;\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tvar c = buffer[start + i];\n\t\t\t\tif (i == 0 && c == '-')\n\t\t\t\t{\n\t\t\t\t\tneg = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if (c < '0' || c > '9')\n\t\t\t\t\tthrow new FormatException();\n\n\t\t\t\tresult = checked(10UL*result + (c - ZERO));\n\t\t\t}\n\n\t\t\tif (neg)\n\t\t\t\treturn -(long) (result);\n\t\t\telse\n\t\t\t\treturn (long) result;\n\t\t}\n\n\t\tpublic static int StringToInt32(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\tconst uint ZERO = (ushort) '0';\n\n\t\t\tvar result = 0u;\n\t\t\tvar neg = false;\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tvar c = buffer[start + i];\n\t\t\t\tif (i == 0 && c == '-')\n\t\t\t\t{\n\t\t\t\t\tneg = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if (c < '0' || c > '9')\n\t\t\t\t\tthrow new FormatException();\n\n\t\t\t\tresult = checked(10u*result + (c - ZERO));\n\t\t\t}\n\n\t\t\tif (neg)\n\t\t\t\treturn -(int) (result);\n\t\t\telse\n\t\t\t\treturn (int) result;\n\t\t}\n\n\t\tpublic static ulong StringToUInt64(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\tconst ulong ZERO = (ushort) '0';\n\n\t\t\tvar result = 0UL;\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tvar c = buffer[start + i];\n\t\t\t\tif (c < '0' || c > '9')\n\t\t\t\t\tthrow new FormatException();\n\n\t\t\t\tresult = checked(10UL*result + (c - ZERO));\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static uint StringToUInt32(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\tconst uint ZERO = (ushort) '0';\n\n\t\t\tvar result = 0U;\n\t\t\tfor (var i = 0; i < len; i++)\n\t\t\t{\n\t\t\t\tvar c = buffer[start + i];\n\t\t\t\tif (c < '0' || c > '9')\n\t\t\t\t\tthrow new FormatException();\n\n\t\t\t\tresult = checked(10*result + (c - ZERO));\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static double StringToDouble(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\t/*\n            const uint ZERO = (ushort)'0';\n            char decimalSep = '.';\n\n            var whole = 0UL;\n            var fraction = 0U;\n            var fracCount = 0;\n            var neg = false;\n            var decimals = false;\n\n            for (var i = 0; i < len; i++)\n            {\n                var c = buffer[start + i];\n                if (i == 0 && c == '-')\n                {\n                    neg = true;\n                    continue;\n                }\n                else if (c == decimalSep)\n                {\n                    decimals = true;\n                    continue;\n                }\n                else if (c < '0' || c > '9')\n                    throw new FormatException();\n\n                if (decimals)\n                {\n                    if (fracCount >= 9) // maximum precision 9 digits\n                        break;\n                    fraction = checked(10U * fraction + (c - ZERO));\n                    fracCount++;\n                }\n                else\n                    whole = checked(10UL * whole + (c - ZERO));\n            }\n\n            var result = checked((double)whole + (fraction / pow10d[fracCount]));\n\n            if (neg) result = -result;\n\n            return result;\n            */\n\n\t\t\treturn double.Parse(new string(buffer, start, len), formatProvider);\n\t\t}\n\n\t\tpublic static float StringToFloat(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\t/*\n            const uint ZERO = (ushort)'0';\n            char decimalSep = '.';\n\n            var whole = 0U;\n            var fraction = 0U;\n            var fracCount = 0;\n            var neg = false;\n            var decimals = false;\n\n            for (var i = 0; i < len; i++)\n            {\n                var c = buffer[start + i];\n                if (i == 0 && c == '-')\n                {\n                    neg = true;\n                    continue;\n                }\n                else if (c == decimalSep)\n                {\n                    decimals = true;\n                    continue;\n                }\n                else if (c < '0' || c > '9')\n                    throw new FormatException();\n\n                if (decimals)\n                {\n                    if (fracCount > 9) // maximum precision 9 digits\n                        break;\n                    fraction = checked(10U * fraction + (c - ZERO));\n                    fracCount++;\n                }\n                else\n                    whole = checked(10U * whole + (c - ZERO));\n            }\n\n            var result = checked((float)whole + (fraction / pow10s[fracCount]));\n\n            if (neg) result = -result;\n\n            return result;\n            */\n\n\t\t\treturn float.Parse(new string(buffer, start, len), formatProvider);\n\t\t}\n\n\t\tpublic static decimal StringToDecimal(char[] buffer, int start, int len, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\t\t\tif (len < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"len\");\n\t\t\tif (start + len > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException();\n\n\n\t\t\treturn decimal.Parse(new string(buffer, start, len), formatProvider);\n\t\t}\n\n\t\tpublic static int Int32ToBuffer(int value, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tconst int ZERO = (ushort) '0';\n\n\t\t\tvar idx = start;\n\t\t\tvar neg = value < 0;\n\t\t\t// Take care of sign\n\t\t\tvar uvalue = neg ? (uint) (-value) : (uint) value;\n\t\t\t// Conversion. Number is reversed.\n\t\t\tdo buffer[idx++] = (char) (ZERO + (uvalue%10)); while ((uvalue /= 10) != 0);\n\t\t\tif (neg) buffer[idx++] = '-';\n\n\t\t\tvar length = idx - start;\n\t\t\t// Reverse string\n\t\t\tArray.Reverse(buffer, start, length);\n\n\t\t\treturn length;\n\t\t}\n\n\t\tpublic static int Int64ToBuffer(long value, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tconst int ZERO = (ushort) '0';\n\n\t\t\tvar idx = start;\n\t\t\t// Take care of sign\n\t\t\tvar neg = (value < 0);\n\t\t\tvar uvalue = neg ? (ulong) (-value) : (ulong) value;\n\t\t\t// Conversion. Number is reversed.\n\t\t\tdo buffer[idx++] = (char) (ZERO + (uvalue%10)); while ((uvalue /= 10) != 0);\n\t\t\tif (neg) buffer[idx++] = '-';\n\n\t\t\tvar length = idx - start;\n\t\t\t// Reverse string\n\t\t\tArray.Reverse(buffer, start, length);\n\n\t\t\treturn length;\n\t\t}\n\n\t\tpublic static int UInt32ToBuffer(uint uvalue, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tconst int ZERO = (ushort) '0';\n\n\t\t\tvar idx = start;\n\t\t\t// Take care of sign\n\t\t\t// Conversion. Number is reversed.\n\t\t\tdo buffer[idx++] = (char) (ZERO + (uvalue%10)); while ((uvalue /= 10) != 0);\n\n\t\t\tvar length = idx - start;\n\t\t\t// Reverse string\n\t\t\tArray.Reverse(buffer, start, length);\n\n\t\t\treturn length;\n\t\t}\n\n\t\tpublic static int UInt64ToBuffer(ulong uvalue, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tconst ulong ZERO = (ulong) '0';\n\n\t\t\tvar idx = start;\n\t\t\t// Conversion. Number is reversed.\n\t\t\tdo buffer[idx++] = (char) (ZERO + (uvalue%10)); while ((uvalue /= 10) != 0UL);\n\n\t\t\tvar length = idx - start;\n\t\t\t// Reverse string\n\t\t\tArray.Reverse(buffer, start, length);\n\n\t\t\treturn length;\n\t\t}\n\n\t\tpublic static int SingleToBuffer(float value, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tvar valueStr = value.ToString(\"R\", formatProvider);\n\t\t\tvalueStr.CopyTo(0, buffer, start, valueStr.Length);\n\t\t\treturn valueStr.Length;\n\t\t}\n\n\t\tpublic static int DoubleToBuffer(double value, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException(\"buffer\");\n\t\t\tif (start < 0 || start >= buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"start\");\n\n\n\t\t\tvar valueStr = value.ToString(\"R\", formatProvider);\n\t\t\tvalueStr.CopyTo(0, buffer, start, valueStr.Length);\n\t\t\treturn valueStr.Length;\n\t\t}\n\n\t\tpublic static int DecimalToBuffer(decimal value, char[] buffer, int start, IFormatProvider formatProvider = null)\n\t\t{\n\t\t\tvar valueStr = value.ToString(null, formatProvider);\n\t\t\tvalueStr.CopyTo(0, buffer, start, valueStr.Length);\n\t\t\treturn valueStr.Length;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonUtils.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 7b759d9c7f3a47f9ab3e9e6059870693\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonWriter.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic abstract class JsonWriter : IJsonWriter\n\t{\n\t\tpublic const int DEFAULT_BUFFER_SIZE = 1024;\n\n\t\t[Flags]\n\t\tprivate enum Structure : byte\n\t\t{\n\t\t\tIsContainer = 0x1,\n\t\t\tIsObject = 0x2 | IsContainer,\n\t\t\tIsArray = 0x4 | IsContainer,\n\t\t\tIsStartOfStructure = 0x1 << 7,\n\t\t\tIsStartOfContainer = IsContainer | IsStartOfStructure\n\t\t}\n\n\t\tprivate const long JS_NUMBER_MAX_VALUE_INT64 = 9007199254740992L;\n\t\tprivate const ulong JS_NUMBER_MAX_VALUE_U_INT64 = 9007199254740992UL;\n\t\tprivate const double JS_NUMBER_MAX_VALUE_DOUBLE = 9007199254740992.0;\n\t\tprivate const double JS_NUMBER_MAX_VALUE_SINGLE = 9007199254740992.0f;\n\t\tprivate const decimal JS_NUMBER_MAX_VALUE_DECIMAL = 9007199254740992.0m;\n\n\t\tprivate static readonly char[] Tabs = new char[] { '\\t', '\\t', '\\t', '\\t', '\\t', '\\t', '\\t', '\\t', '\\t', '\\t' };\n\t\tprivate static readonly char[] Newline = \"\\r\\n\".ToCharArray();\n\t\tprivate static readonly char[] NameSeparator = \":\".ToCharArray();\n\t\tprivate static readonly char[] ValueSeparator = \",\".ToCharArray();\n\t\tprivate static readonly char[] ArrayBegin = \"[\".ToCharArray();\n\t\tprivate static readonly char[] ArrayEnd = \"]\".ToCharArray();\n\t\tprivate static readonly char[] ObjectBegin = \"{\".ToCharArray();\n\t\tprivate static readonly char[] ObjectEnd = \"}\".ToCharArray();\n\t\tprivate static readonly char[] Null = \"null\".ToCharArray();\n\t\tprivate static readonly char[] True = \"true\".ToCharArray();\n\t\tprivate static readonly char[] False = \"false\".ToCharArray();\n\n\t\tprivate readonly Stack<Structure> structStack;\n\t\tprivate readonly char[] buffer;\n\n\t\tpublic SerializationContext Context { get; private set; }\n\t\tpublic long CharactersWritten { get; protected set; }\n\t\tpublic int InitialPadding { get; set; }\n\n\t\tprotected JsonWriter(SerializationContext context, char[] buffer = null)\n\t\t{\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (buffer != null && buffer.Length < 1024) throw new ArgumentOutOfRangeException(\"buffer\", \"Buffer should be at least 1024 bytes long.\");\n\n\t\t\tthis.Context = context;\n\t\t\tthis.buffer = buffer ?? new char[DEFAULT_BUFFER_SIZE];\n\t\t\tthis.structStack = new Stack<Structure>(10);\n\t\t}\n\n\t\tpublic abstract void Flush();\n\t\tpublic abstract void WriteJson(string jsonString);\n\t\tpublic abstract void WriteJson(char[] jsonString, int offset, int charactersToWrite);\n\n\t\tpublic void Write(string value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tthis.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.WriteFormatting(JsonToken.StringLiteral);\n\n\t\t\tvar len = value.Length;\n\t\t\tvar offset = 0;\n\t\t\tthis.buffer[0] = '\"';\n\t\t\tthis.WriteJson(this.buffer, 0, 1);\n\t\t\twhile (offset < len)\n\t\t\t{\n\t\t\t\tvar writtenInBuffer = JsonUtils.EscapeBuffer(value, ref offset, this.buffer, 0);\n\t\t\t\tthis.WriteJson(this.buffer, 0, writtenInBuffer);\n\t\t\t}\n\n\t\t\tthis.buffer[0] = '\"';\n\t\t\tthis.WriteJson(this.buffer, 0, 1);\n\t\t}\n\t\tpublic void Write(JsonMember member)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Member);\n\n\t\t\tif (member.IsEscapedAndQuoted)\n\t\t\t{\n\t\t\t\tif (member.NameString != null)\n\t\t\t\t\tthis.WriteJson(member.NameString);\n\t\t\t\telse\n\t\t\t\t\tthis.WriteJson(member.NameChars, 0, member.NameChars.Length);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (member.NameString != null)\n\t\t\t\t\tthis.WriteString(member.NameString);\n\t\t\t\telse\n\t\t\t\t\tthis.WriteString(new string(member.NameChars));\n\n\t\t\t\tthis.WriteJson(NameSeparator, 0, NameSeparator.Length);\n\t\t\t}\n\t\t}\n\t\tpublic void Write(int number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.Int32ToBuffer(number, this.buffer, 0, this.Context.Format);\n\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(uint number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.UInt32ToBuffer(number, this.buffer, 0, this.Context.Format);\n\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(long number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.Int64ToBuffer(number, this.buffer, 0, this.Context.Format);\n\n\t\t\tif (number > JS_NUMBER_MAX_VALUE_INT64)\n\t\t\t\tthis.WriteString(new string(this.buffer, 0, len));\n\t\t\telse\n\t\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(ulong number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.UInt64ToBuffer(number, this.buffer, 0, this.Context.Format);\n\n\t\t\tif (number > JS_NUMBER_MAX_VALUE_U_INT64)\n\t\t\t\tthis.WriteString(new string(this.buffer, 0, len));\n\t\t\telse\n\t\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(float number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.SingleToBuffer(number, this.buffer, 0, this.Context.Format);\n\t\t\tif (number > JS_NUMBER_MAX_VALUE_SINGLE)\n\t\t\t\tthis.WriteString(new string(this.buffer, 0, len));\n\t\t\telse\n\t\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(double number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.DoubleToBuffer(number, this.buffer, 0, this.Context.Format);\n\t\t\tif (number > JS_NUMBER_MAX_VALUE_DOUBLE)\n\t\t\t\tthis.WriteString(new string(this.buffer, 0, len));\n\t\t\telse\n\t\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(decimal number)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Number);\n\n\t\t\tvar len = JsonUtils.DecimalToBuffer(number, this.buffer, 0, this.Context.Format);\n\t\t\tif (number > JS_NUMBER_MAX_VALUE_DECIMAL)\n\t\t\t\tthis.WriteString(new string(this.buffer, 0, len));\n\t\t\telse\n\t\t\t\tthis.WriteJson(this.buffer, 0, len);\n\t\t}\n\t\tpublic void Write(DateTime dateTime)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.DateTime);\n\n\t\t\tif (dateTime.Kind == DateTimeKind.Unspecified)\n\t\t\t\tdateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc);\n\n\t\t\tvar dateTimeFormat = this.Context.DateTimeFormats.FirstOrDefault() ?? \"o\";\n\t\t\tif (dateTimeFormat.IndexOf('z') >= 0 && dateTime.Kind != DateTimeKind.Local)\n\t\t\t\tdateTime = dateTime.ToLocalTime();\n\n\t\t\tvar dateString = dateTime.ToString(dateTimeFormat, this.Context.Format);\n\n\t\t\tthis.Write(dateString);\n\t\t}\n\t\tpublic void Write(DateTimeOffset dateTimeOffset)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.DateTime);\n\n\t\t\tvar dateTimeFormat = this.Context.DateTimeFormats.FirstOrDefault() ?? \"o\";\n\t\t\tvar dateString = dateTimeOffset.ToString(dateTimeFormat, this.Context.Format);\n\t\t\tthis.Write(dateString);\n\t\t}\n\t\tpublic void Write(bool value)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Boolean);\n\n\t\t\tif (value)\n\t\t\t\tthis.WriteJson(True, 0, True.Length);\n\t\t\telse\n\t\t\t\tthis.WriteJson(False, 0, False.Length);\n\t\t}\n\t\tpublic void WriteObjectBegin(int numberOfMembers)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.BeginObject);\n\n\t\t\tthis.structStack.Push(Structure.IsObject | Structure.IsStartOfStructure);\n\t\t\tthis.WriteJson(ObjectBegin, 0, ObjectBegin.Length);\n\t\t}\n\t\tpublic void WriteObjectEnd()\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.EndOfObject);\n\n\t\t\tthis.structStack.Pop();\n\t\t\tthis.WriteNewlineAndPad(0);\n\t\t\tthis.WriteJson(ObjectEnd, 0, ObjectEnd.Length);\n\t\t}\n\t\tpublic void WriteArrayBegin(int numberOfMembers)\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.BeginArray);\n\n\t\t\tthis.structStack.Push(Structure.IsArray | Structure.IsStartOfStructure);\n\t\t\tthis.WriteJson(ArrayBegin, 0, ArrayBegin.Length);\n\t\t}\n\t\tpublic void WriteArrayEnd()\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.EndOfArray);\n\n\t\t\tthis.structStack.Pop();\n\t\t\tthis.WriteJson(ArrayEnd, 0, ArrayEnd.Length);\n\t\t}\n\t\tpublic void WriteNull()\n\t\t{\n\t\t\tthis.WriteFormatting(JsonToken.Null);\n\n\t\t\tthis.WriteJson(Null, 0, Null.Length);\n\t\t}\n\n\t\tpublic void Reset()\n\t\t{\n\t\t\tthis.CharactersWritten = 0;\n\t\t\tthis.structStack.Clear();\n\t\t}\n\n\t\tprivate void WriteNewlineAndPad(int correction)\n\t\t{\n\t\t\tif ((this.Context.Options & SerializationOptions.PrettyPrint) != SerializationOptions.PrettyPrint)\n\t\t\t\treturn;\n\n\t\t\t// add padings and linebreaks\n\t\t\tthis.WriteJson(Newline, 0, Newline.Length);\n\t\t\tvar tabs = this.structStack.Count + correction;\n\t\t\twhile (tabs > 0)\n\t\t\t{\n\t\t\t\tthis.WriteJson(Tabs, 0, Math.Min(tabs, Tabs.Length));\n\t\t\t\ttabs -= Tabs.Length;\n\t\t\t}\n\t\t}\n\t\tprivate void WriteFormatting(JsonToken token)\n\t\t{\n\t\t\tif (this.structStack.Count <= 0)\n\t\t\t\treturn;\n\n\t\t\tvar stackPeek = this.structStack.Peek();\n\t\t\tvar isNotMemberValue = ((stackPeek & Structure.IsObject) != Structure.IsObject || token == JsonToken.Member);\n\t\t\tvar isEndToken = token == JsonToken.EndOfArray || token == JsonToken.EndOfObject;\n\n\t\t\tif ((stackPeek & Structure.IsContainer) != Structure.IsContainer || !isNotMemberValue)\n\t\t\t\treturn;\n\n\t\t\t// it's a begining of container we add padding and remove \"is begining\" flag\n\t\t\tif ((stackPeek & Structure.IsStartOfContainer) == Structure.IsStartOfContainer)\n\t\t\t{\n\t\t\t\tstackPeek = this.structStack.Pop();\n\t\t\t\tthis.structStack.Push(stackPeek ^ Structure.IsStartOfStructure); // revert \"is begining\"\n\t\t\t}\n\t\t\t// else if it's new array's value or new object's member put comman and padding\n\t\t\telse if (!isEndToken)\n\t\t\t\tthis.WriteJson(ValueSeparator, 0, ValueSeparator.Length);\n\n\t\t\t// padding\n\t\t\t// pad only before member in object container(not before value, it's ugly)\n\t\t\tthis.WriteNewlineAndPad(this.InitialPadding + (isEndToken ? -1 : 0));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonWriter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: ada1b1f263fd495d816316581abc506d\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonWriterExtentions.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic static class JsonWriterExtentions\n\t{\n\t\tpublic static void WriteMember(this IJsonWriter writer, string memberName)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (memberName == null) throw new ArgumentNullException(\"memberName\");\n\n\t\t\twriter.Write((JsonMember)memberName);\n\t\t}\n\n\t\tpublic static void WriteDateTime(this IJsonWriter writer, DateTime date)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(date);\n\t\t}\n\t\tpublic static void WriteDateTime(this IJsonWriter writer, DateTime? date)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (date == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(date.Value);\n\t\t}\n\n\t\tpublic static void WriteBoolean(this IJsonWriter writer, bool value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(value);\n\t\t}\n\t\tpublic static void WriteBoolean(this IJsonWriter writer, bool? value)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (value == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(value.Value);\n\t\t}\n\n\t\tpublic static void WriteNumber(this IJsonWriter writer, byte number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, sbyte number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, short number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, ushort number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, int number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, uint number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, long number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, ulong number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, float number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, double number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, decimal number)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\twriter.Write(number);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, byte? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, sbyte? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, short? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, ushort? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, int? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, uint? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, long? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, ulong? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, float? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, double? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\t\tpublic static void WriteNumber(this IJsonWriter writer, decimal? number)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (number == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(number.Value);\n\t\t}\n\n\t\tpublic static void WriteString(this IJsonWriter writer, string literal)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(\"writer\");\n\n\n\t\t\tif (literal == null)\n\t\t\t\twriter.WriteNull();\n\t\t\telse\n\t\t\t\twriter.Write(literal);\n\t\t}\n\n\t\tpublic static void WriteValue(this IJsonWriter writer, object value, Type valueType)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\twriter.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar actualValueType = value.GetType();\n\t\t\tvar serializer = writer.Context.GetSerializerForType(actualValueType);\n\t\t\t//var objectSerializer = serializer as ObjectSerializer;\n\t\t\t//if (objectSerializer != null && valueType == actualValueType)\n\t\t\t//\tobjectSerializer.SuppressTypeInformation = true; // no need to write type information on when type is obvious\n\n\t\t\tserializer.Serialize(writer, value);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/JsonWriterExtentions.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 094b3892dad14bb1858f6e2f26adc4f7\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/BigEndianBitConverter.cs",
    "content": "//\n/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see\nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse\nor promote products derived from this software without prior written\npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called\n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n*/\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t/// <summary>\n\t///     Implementation of EndianBitConverter which converts to/from big-endian\n\t///     byte arrays.\n\t/// </summary>\n\tinternal sealed class BigEndianBitConverter : EndianBitConverter\n\t{\n\t\t/// <summary>\n\t\t///     Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t///     Different computer architectures store data using different byte orders. \"Big-endian\"\n\t\t///     means the most significant byte is on the left end of a word. \"Little-endian\" means the\n\t\t///     most significant byte is on the right end of a word.\n\t\t/// </remarks>\n\t\t/// <returns>true if this converter is little-endian, false otherwise.</returns>\n\t\tpublic override sealed bool IsLittleEndian()\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\tpublic override sealed Endianness Endianness\n\t\t{\n\t\t\tget { return Endianness.BigEndian; }\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified number of bytes from value to buffer, starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy</param>\n\t\t/// <param name=\"bytes\">The number of bytes to copy</param>\n\t\t/// <param name=\"buffer\">The buffer to copy the bytes into</param>\n\t\t/// <param name=\"index\">The index to start at</param>\n\t\tprotected override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)\n\t\t{\n\t\t\tvar endOffset = index + bytes - 1;\n\t\t\tfor (var i = 0; i < bytes; i++)\n\t\t\t{\n\t\t\t\tbuffer[endOffset - i] = unchecked((byte) (value & 0xff));\n\t\t\t\tvalue = value >> 8;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a value built from the specified number of bytes from the given buffer,\n\t\t///     starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"buffer\">The data in byte array format</param>\n\t\t/// <param name=\"startIndex\">The first index to use</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to use</param>\n\t\t/// <returns>The value built from the given bytes</returns>\n\t\tprotected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)\n\t\t{\n\t\t\tlong ret = 0;\n\t\t\tfor (var i = 0; i < bytesToConvert; i++)\n\t\t\t{\n\t\t\t\tret = unchecked((ret << 8) | buffer[startIndex + i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/BigEndianBitConverter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: d3103829396f4f9780c29cf3fdafe3d9\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/DefaultMsgPackExtensionTypeHandler.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\tpublic sealed class DefaultMessagePackExtensionTypeHandler : MessagePackExtensionTypeHandler\n\t{\n\t\tpublic const int EXTENSION_TYPE_TIMESTAMP = -1;\n\t\tpublic const int EXTENSION_TYPE_DATE_TIME = 40;\n\t\tpublic const int EXTENSION_TYPE_DATE_TIME_OFFSET = 41;\n\t\tpublic const int EXTENSION_TYPE_DECIMAL = 42;\n\t\tpublic const int EXTENSION_TYPE_GUID = 43;\n\t\tpublic const int GUID_SIZE = 16;\n\t\tpublic const int DECIMAL_SIZE = 16;\n\t\tpublic const int DATE_TIME_SIZE = 16;\n\t\tpublic const int DATE_TIME_OFFSET_SIZE = 16;\n\n\t\tprivate static readonly Type[] DefaultExtensionTypes = new[] { typeof(decimal), typeof(DateTime), typeof(DateTimeOffset), typeof(Guid), typeof(DateTimeOffset), typeof(MessagePackTimestamp) };\n\t\tpublic static DefaultMessagePackExtensionTypeHandler Instance = new DefaultMessagePackExtensionTypeHandler(EndianBitConverter.Little);\n\n\t\tprivate readonly EndianBitConverter bitConverter;\n\n\t\tpublic override IEnumerable<Type> ExtensionTypes\n\t\t{\n\t\t\tget { return DefaultExtensionTypes; }\n\t\t}\n\n\t\tinternal DefaultMessagePackExtensionTypeHandler(EndianBitConverter bitConverter)\n\t\t{\n\t\t\tif (bitConverter == null) throw new ArgumentNullException(\"bitConverter\");\n\n\t\t\tthis.bitConverter = bitConverter;\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic override bool TryRead(sbyte type, ArraySegment<byte> data, out object value)\n\t\t{\n\t\t\tif (data.Array == null) throw new ArgumentNullException(\"data\");\n\n\t\t\tvalue = default(object);\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase EXTENSION_TYPE_TIMESTAMP:\n\t\t\t\t\tunchecked\n\t\t\t\t\t{\n\t\t\t\t\t\tvar seconds = 0L;\n\t\t\t\t\t\tvar nanoSeconds = 0u;\n\t\t\t\t\t\tswitch (data.Count)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase 4:\n\t\t\t\t\t\t\t\tseconds = this.bitConverter.ToInt32(data.Array, data.Offset);\n\t\t\t\t\t\t\t\tvalue = new MessagePackTimestamp(seconds, nanoSeconds);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tcase 8:\n\t\t\t\t\t\t\t\tvar data64 = this.bitConverter.ToUInt64(data.Array, data.Offset);\n\t\t\t\t\t\t\t\tseconds = (int)(data64 & 0x00000003ffffffffL);\n\t\t\t\t\t\t\t\tnanoSeconds = (uint)(data64 >> 34 & uint.MaxValue);\n\t\t\t\t\t\t\t\tvalue = new MessagePackTimestamp(seconds, nanoSeconds);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tcase 12:\n\t\t\t\t\t\t\t\tnanoSeconds = this.bitConverter.ToUInt32(data.Array, data.Offset);\n\t\t\t\t\t\t\t\tseconds = this.bitConverter.ToInt64(data.Array, data.Offset + 4);\n\t\t\t\t\t\t\t\tvalue = new MessagePackTimestamp(seconds, nanoSeconds);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tcase EXTENSION_TYPE_DATE_TIME:\n\t\t\t\t\tif (data.Count != DATE_TIME_SIZE)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar dateTime = new DateTime(this.bitConverter.ToInt64(data.Array, data.Offset + 1), (DateTimeKind)data.Array[data.Offset]);\n\t\t\t\t\tvalue = dateTime;\n\t\t\t\t\treturn true;\n\t\t\t\tcase EXTENSION_TYPE_DATE_TIME_OFFSET:\n\t\t\t\t\tif (data.Count != DATE_TIME_OFFSET_SIZE)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar offset = new TimeSpan(this.bitConverter.ToInt64(data.Array, data.Offset + 8));\n\t\t\t\t\tvar ticks = this.bitConverter.ToInt64(data.Array, data.Offset);\n\t\t\t\t\tvar dateTimeOffset = new DateTimeOffset(ticks, offset);\n\t\t\t\t\tvalue = dateTimeOffset;\n\t\t\t\t\treturn true;\n\t\t\t\tcase EXTENSION_TYPE_DECIMAL:\n\t\t\t\t\tif (data.Count != DECIMAL_SIZE)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar decimalValue = this.bitConverter.ToDecimal(data.Array, data.Offset);\n\t\t\t\t\tvalue = decimalValue;\n\t\t\t\t\treturn true;\n\t\t\t\tcase EXTENSION_TYPE_GUID:\n\t\t\t\t\tif (data.Count != GUID_SIZE)\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tvar buffer = data.Array;\n\t\t\t\t\tunchecked\n\t\t\t\t\t{\n\t\t\t\t\t\tvar guidValue = new Guid\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(uint)(buffer[data.Offset + 3] << 24 | buffer[data.Offset + 2] << 16 | buffer[data.Offset + 1] << 8 | buffer[data.Offset + 0]),\n\t\t\t\t\t\t\t(ushort)(buffer[data.Offset + 5] << 8 | buffer[data.Offset + 4]),\n\t\t\t\t\t\t\t(ushort)(buffer[data.Offset + 7] << 8 | buffer[data.Offset + 6]),\n\t\t\t\t\t\t\tbuffer[data.Offset + 8],\n\t\t\t\t\t\t\tbuffer[data.Offset + 9],\n\t\t\t\t\t\t\tbuffer[data.Offset + 10],\n\t\t\t\t\t\t\tbuffer[data.Offset + 11],\n\t\t\t\t\t\t\tbuffer[data.Offset + 12],\n\t\t\t\t\t\t\tbuffer[data.Offset + 13],\n\t\t\t\t\t\t\tbuffer[data.Offset + 14],\n\t\t\t\t\t\t\tbuffer[data.Offset + 15]\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tvalue = guidValue;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic override bool TryWrite(object value, out sbyte type, ref ArraySegment<byte> data)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\ttype = 0;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (value is DateTime)\n\t\t\t{\n\t\t\t\ttype = EXTENSION_TYPE_DATE_TIME;\n\t\t\t\tif (data.Array == null || data.Count < DATE_TIME_SIZE)\n\t\t\t\t\tdata = new ArraySegment<byte>(new byte[DATE_TIME_SIZE]);\n\n\t\t\t\tvar dateTime = (DateTime)(object)value;\n\t\t\t\tArray.Clear(data.Array, data.Offset, DATE_TIME_SIZE);\n\t\t\t\tthis.bitConverter.CopyBytes(dateTime.Ticks, data.Array, data.Offset + 1);\n\t\t\t\tdata.Array[data.Offset] = (byte)dateTime.Kind;\n\n\t\t\t\tif (data.Count != DATE_TIME_SIZE)\n\t\t\t\t\tdata = new ArraySegment<byte>(data.Array, data.Offset, DATE_TIME_SIZE);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (value is DateTimeOffset)\n\t\t\t{\n\t\t\t\ttype = EXTENSION_TYPE_DATE_TIME_OFFSET;\n\t\t\t\tif (data.Array == null || data.Count < DATE_TIME_OFFSET_SIZE)\n\t\t\t\t\tdata = new ArraySegment<byte>(new byte[DATE_TIME_OFFSET_SIZE]);\n\n\t\t\t\tvar dateTimeOffset = (DateTimeOffset)(object)value;\n\t\t\t\tthis.bitConverter.CopyBytes(dateTimeOffset.DateTime.Ticks, data.Array, data.Offset);\n\t\t\t\tthis.bitConverter.CopyBytes(dateTimeOffset.Offset.Ticks, data.Array, data.Offset + 8);\n\n\t\t\t\tif (data.Count != DATE_TIME_OFFSET_SIZE)\n\t\t\t\t\tdata = new ArraySegment<byte>(data.Array, data.Offset, DATE_TIME_OFFSET_SIZE);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (value is decimal)\n\t\t\t{\n\n\t\t\t\ttype = EXTENSION_TYPE_DECIMAL;\n\t\t\t\tif (data.Array == null || data.Count < DECIMAL_SIZE)\n\t\t\t\t\tdata = new ArraySegment<byte>(new byte[DECIMAL_SIZE]);\n\n\t\t\t\tvar number = (decimal)(object)value;\n\t\t\t\tthis.bitConverter.CopyBytes(number, data.Array, data.Offset);\n\n\t\t\t\tif (data.Count != DECIMAL_SIZE)\n\t\t\t\t\tdata = new ArraySegment<byte>(data.Array, data.Offset, DECIMAL_SIZE);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (value is Guid)\n\t\t\t{\n\t\t\t\ttype = EXTENSION_TYPE_GUID;\n\t\t\t\tvar guid = (Guid)(object)value;\n\t\t\t\tdata = new ArraySegment<byte>(guid.ToByteArray());\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (value is MessagePackTimestamp)\n\t\t\t{\n\t\t\t\ttype = EXTENSION_TYPE_TIMESTAMP;\n\t\t\t\tvar timestamp = (MessagePackTimestamp)(object)value;\n\n\t\t\t\tunchecked\n\t\t\t\t{\n\n\t\t\t\t\tif (timestamp.Seconds <= int.MaxValue && timestamp.Seconds >= int.MinValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (timestamp.NanoSeconds == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst int TIMESTAMP_SIZE = 4;\n\n\t\t\t\t\t\t\tif (data.Array == null || data.Count < TIMESTAMP_SIZE)\n\t\t\t\t\t\t\t\tdata = new ArraySegment<byte>(new byte[TIMESTAMP_SIZE]);\n\n\t\t\t\t\t\t\t// timestamp 32\n\t\t\t\t\t\t\tthis.bitConverter.CopyBytes((int)timestamp.Seconds, data.Array, data.Offset);\n\n\t\t\t\t\t\t\tif (data.Count != TIMESTAMP_SIZE)\n\t\t\t\t\t\t\t\tdata = new ArraySegment<byte>(data.Array, data.Offset, TIMESTAMP_SIZE);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst int TIMESTAMP_SIZE = 8;\n\n\t\t\t\t\t\t\tif (data.Array == null || data.Count < TIMESTAMP_SIZE)\n\t\t\t\t\t\t\t\tdata = new ArraySegment<byte>(new byte[TIMESTAMP_SIZE]);\n\n\t\t\t\t\t\t\tvar data64 = ((ulong)timestamp.NanoSeconds << 34) | ((ulong)timestamp.Seconds & uint.MaxValue);\n\t\t\t\t\t\t\t// timestamp 64\n\t\t\t\t\t\t\tthis.bitConverter.CopyBytes(data64, data.Array, data.Offset);\n\n\t\t\t\t\t\t\tif (data.Count != TIMESTAMP_SIZE)\n\t\t\t\t\t\t\t\tdata = new ArraySegment<byte>(data.Array, data.Offset, TIMESTAMP_SIZE);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tconst int TIMESTAMP_SIZE = 12;\n\n\t\t\t\t\t\tif (data.Array == null || data.Count < TIMESTAMP_SIZE)\n\t\t\t\t\t\t\tdata = new ArraySegment<byte>(new byte[TIMESTAMP_SIZE]);\n\n\t\t\t\t\t\t// timestamp 96\n\t\t\t\t\t\tthis.bitConverter.CopyBytes(timestamp.NanoSeconds, data.Array, data.Offset);\n\t\t\t\t\t\tthis.bitConverter.CopyBytes(timestamp.Seconds, data.Array, data.Offset + 4);\n\n\t\t\t\t\t\tif (data.Count != TIMESTAMP_SIZE)\n\t\t\t\t\t\t\tdata = new ArraySegment<byte>(data.Array, data.Offset, TIMESTAMP_SIZE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttype = default(sbyte);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/DefaultMsgPackExtensionTypeHandler.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 7ed197b91d8b44368f386ccbde8ee57f\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/EndianBitConverter.cs",
    "content": "//\n/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see\nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse\nor promote products derived from this software without prior written\npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called\n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n*/\n\nusing System;\nusing System.Runtime.InteropServices;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t/// <summary>\n\t///     Equivalent of System.BitConverter, but with either endianness.\n\t/// </summary>\n\tinternal abstract class EndianBitConverter\n\t{\n\t\t#region Endianness of this converter\n\n\t\t/// <summary>\n\t\t///     Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t///     Different computer architectures store data using different byte orders. \"Big-endian\"\n\t\t///     means the most significant byte is on the left end of a word. \"Little-endian\" means the\n\t\t///     most significant byte is on the right end of a word.\n\t\t/// </remarks>\n\t\t/// <returns>true if this converter is little-endian, false otherwise.</returns>\n\t\tpublic abstract bool IsLittleEndian();\n\n\t\t/// <summary>\n\t\t///     Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\tpublic abstract Endianness Endianness { get; }\n\n\t\t#endregion\n\n\t\t#region Factory properties\n\n\t\tprivate static readonly LittleEndianBitConverter little = new LittleEndianBitConverter();\n\n\t\t/// <summary>\n\t\t///     Returns a little-endian bit converter instance. The same instance is\n\t\t///     always returned.\n\t\t/// </summary>\n\t\tpublic static LittleEndianBitConverter Little\n\t\t{\n\t\t\tget { return little; }\n\t\t}\n\n\t\tprivate static readonly BigEndianBitConverter big = new BigEndianBitConverter();\n\n\t\t/// <summary>\n\t\t///     Returns a big-endian bit converter instance. The same instance is\n\t\t///     always returned.\n\t\t/// </summary>\n\t\tpublic static BigEndianBitConverter Big\n\t\t{\n\t\t\tget { return big; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Double/primitive conversions\n\n\t\t/// <summary>\n\t\t///     Converts the specified double-precision floating point number to a\n\t\t///     64-bit signed integer. Note: the endianness of this converter does not\n\t\t///     affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A 64-bit signed integer whose value is equivalent to value.</returns>\n\t\tpublic long DoubleToInt64Bits(double value)\n\t\t{\n\t\t\treturn BitConverter.DoubleToInt64Bits(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Converts the specified 64-bit signed integer to a double-precision\n\t\t///     floating point number. Note: the endianness of this converter does not\n\t\t///     affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A double-precision floating point number whose value is equivalent to value.</returns>\n\t\tpublic double Int64BitsToDouble(long value)\n\t\t{\n\t\t\treturn BitConverter.Int64BitsToDouble(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Converts the specified single-precision floating point number to a\n\t\t///     32-bit signed integer. Note: the endianness of this converter does not\n\t\t///     affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A 32-bit signed integer whose value is equivalent to value.</returns>\n\t\tpublic int SingleToInt32Bits(float value)\n\t\t{\n\t\t\treturn new Int32SingleUnion(value).AsInt32;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Converts the specified 32-bit signed integer to a single-precision floating point\n\t\t///     number. Note: the endianness of this converter does not\n\t\t///     affect the returned value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert. </param>\n\t\t/// <returns>A single-precision floating point number whose value is equivalent to value.</returns>\n\t\tpublic float Int32BitsToSingle(int value)\n\t\t{\n\t\t\treturn new Int32SingleUnion(value).AsSingle;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region To(PrimitiveType) conversions\n\n\t\t/// <summary>\n\t\t///     Returns a Boolean value converted from one byte at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>true if the byte at startIndex in value is nonzero; otherwise, false.</returns>\n\t\tpublic bool ToBoolean(byte[] value, int startIndex)\n\t\t{\n\t\t\tCheckByteArgument(value, startIndex, 1);\n\t\t\treturn BitConverter.ToBoolean(value, startIndex);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a Unicode character converted from two bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A character formed by two bytes beginning at startIndex.</returns>\n\t\tpublic char ToChar(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((char) (CheckedFromBytes(value, startIndex, 2)));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a double-precision floating point number converted from eight bytes\n\t\t///     at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A double precision floating point number formed by eight bytes beginning at startIndex.</returns>\n\t\tpublic double ToDouble(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn Int64BitsToDouble(ToInt64(value, startIndex));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a single-precision floating point number converted from four bytes\n\t\t///     at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A single precision floating point number formed by four bytes beginning at startIndex.</returns>\n\t\tpublic float ToSingle(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn Int32BitsToSingle(ToInt32(value, startIndex));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 16-bit signed integer formed by two bytes beginning at startIndex.</returns>\n\t\tpublic short ToInt16(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((short) (CheckedFromBytes(value, startIndex, 2)));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 32-bit signed integer formed by four bytes beginning at startIndex.</returns>\n\t\tpublic int ToInt32(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((int) (CheckedFromBytes(value, startIndex, 4)));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 64-bit signed integer formed by eight bytes beginning at startIndex.</returns>\n\t\tpublic long ToInt64(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn CheckedFromBytes(value, startIndex, 8);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>\n\t\tpublic ushort ToUInt16(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((ushort) (CheckedFromBytes(value, startIndex, 2)));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>\n\t\tpublic uint ToUInt32(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((uint) (CheckedFromBytes(value, startIndex, 4)));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A 64-bit unsigned integer formed by eight bytes beginning at startIndex.</returns>\n\t\tpublic ulong ToUInt64(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn unchecked((ulong) (CheckedFromBytes(value, startIndex, 8)));\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Checks the given argument for validity.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The byte array passed in</param>\n\t\t/// <param name=\"startIndex\">The start index passed in</param>\n\t\t/// <param name=\"bytesRequired\">The number of bytes required</param>\n\t\t/// <exception cref=\"ArgumentNullException\">value is a null reference</exception>\n\t\t/// <exception cref=\"ArgumentOutOfRangeException\">\n\t\t///     startIndex is less than zero or greater than the length of value minus bytesRequired.\n\t\t/// </exception>\n\t\tprivate static void CheckByteArgument(byte[] value, int startIndex, int bytesRequired)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(\"value\");\n\t\t\t}\n\t\t\tif (startIndex < 0 || startIndex > value.Length - bytesRequired)\n\t\t\t{\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"startIndex\");\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Checks the arguments for validity before calling FromBytes\n\t\t///     (which can therefore assume the arguments are valid).\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The bytes to convert after checking</param>\n\t\t/// <param name=\"startIndex\">The index of the first byte to convert</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to convert</param>\n\t\t/// <returns></returns>\n\t\tprivate long CheckedFromBytes(byte[] value, int startIndex, int bytesToConvert)\n\t\t{\n\t\t\tCheckByteArgument(value, startIndex, bytesToConvert);\n\t\t\treturn FromBytes(value, startIndex, bytesToConvert);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Convert the given number of bytes from the given array, from the given start\n\t\t///     position, into a long, using the bytes as the least significant part of the long.\n\t\t///     By the time this is called, the arguments have been checked for validity.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The bytes to convert</param>\n\t\t/// <param name=\"startIndex\">The index of the first byte to convert</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to use in the conversion</param>\n\t\t/// <returns>The converted number</returns>\n\t\tprotected abstract long FromBytes(byte[] value, int startIndex, int bytesToConvert);\n\n\t\t#endregion\n\n\t\t#region ToString conversions\n\n\t\t/// <summary>\n\t\t///     Returns a String converted from the elements of a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <remarks>All the elements of value are converted.</remarks>\n\t\t/// <returns>\n\t\t///     A String of hexadecimal pairs separated by hyphens, where each pair\n\t\t///     represents the corresponding element in value; for example, \"7F-2C-4A\".\n\t\t/// </returns>\n\t\tpublic static string ToString(byte[] value)\n\t\t{\n\t\t\treturn BitConverter.ToString(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a String converted from the elements of a byte array starting at a specified array position.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <remarks>The elements from array position startIndex to the end of the array are converted.</remarks>\n\t\t/// <returns>\n\t\t///     A String of hexadecimal pairs separated by hyphens, where each pair\n\t\t///     represents the corresponding element in value; for example, \"7F-2C-4A\".\n\t\t/// </returns>\n\t\tpublic static string ToString(byte[] value, int startIndex)\n\t\t{\n\t\t\treturn BitConverter.ToString(value, startIndex);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a String converted from a specified number of bytes at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <param name=\"length\">The number of bytes to convert.</param>\n\t\t/// <remarks>The length elements from array position startIndex are converted.</remarks>\n\t\t/// <returns>\n\t\t///     A String of hexadecimal pairs separated by hyphens, where each pair\n\t\t///     represents the corresponding element in value; for example, \"7F-2C-4A\".\n\t\t/// </returns>\n\t\tpublic static string ToString(byte[] value, int startIndex, int length)\n\t\t{\n\t\t\treturn BitConverter.ToString(value, startIndex, length);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region\tDecimal conversions\n\n\t\t/// <summary>\n\t\t///     Returns a decimal value converted from sixteen bytes\n\t\t///     at a specified position in a byte array.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">An array of bytes.</param>\n\t\t/// <param name=\"startIndex\">The starting position within value.</param>\n\t\t/// <returns>A decimal  formed by sixteen bytes beginning at startIndex.</returns>\n\t\tpublic decimal ToDecimal(byte[] value, int startIndex)\n\t\t{\n\t\t\t// HACK: This always assumes four parts, each in their own endianness,\n\t\t\t// starting with the first part at the start of the byte array.\n\t\t\t// On the other hand, there's no real format specified...\n\t\t\tvar parts = new int[4];\n\t\t\tfor (var i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tparts[i] = ToInt32(value, startIndex + i*4);\n\t\t\t}\n\t\t\treturn new decimal(parts);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified decimal value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 16.</returns>\n\t\tpublic byte[] GetBytes(decimal value)\n\t\t{\n\t\t\tvar bytes = new byte[16];\n\t\t\tvar parts = decimal.GetBits(value);\n\t\t\tfor (var i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tCopyBytesImpl(parts[i], 4, bytes, i*4);\n\t\t\t}\n\t\t\treturn bytes;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified decimal value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A character to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(decimal value, byte[] buffer, int index)\n\t\t{\n\t\t\tvar parts = decimal.GetBits(value);\n\t\t\tfor (var i = 0; i < 4; i++)\n\t\t\t{\n\t\t\t\tCopyBytesImpl(parts[i], 4, buffer, i*4 + index);\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region GetBytes conversions\n\n\t\t/// <summary>\n\t\t///     Returns an array with the given number of bytes formed\n\t\t///     from the least significant bytes of the specified value.\n\t\t///     This is used to implement the other GetBytes methods.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to get bytes for</param>\n\t\t/// <param name=\"bytes\">The number of significant bytes to return</param>\n\t\tprivate byte[] GetBytes(long value, int bytes)\n\t\t{\n\t\t\tvar buffer = new byte[bytes];\n\t\t\tCopyBytes(value, bytes, buffer, 0);\n\t\t\treturn buffer;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified Boolean value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A Boolean value.</param>\n\t\t/// <returns>An array of bytes with length 1.</returns>\n\t\tpublic byte[] GetBytes(bool value)\n\t\t{\n\t\t\treturn BitConverter.GetBytes(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified Unicode character value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A character to convert.</param>\n\t\t/// <returns>An array of bytes with length 2.</returns>\n\t\tpublic byte[] GetBytes(char value)\n\t\t{\n\t\t\treturn GetBytes(value, 2);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified double-precision floating point value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 8.</returns>\n\t\tpublic byte[] GetBytes(double value)\n\t\t{\n\t\t\treturn GetBytes(DoubleToInt64Bits(value), 8);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified 16-bit signed integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 2.</returns>\n\t\tpublic byte[] GetBytes(short value)\n\t\t{\n\t\t\treturn GetBytes(value, 2);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified 32-bit signed integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 4.</returns>\n\t\tpublic byte[] GetBytes(int value)\n\t\t{\n\t\t\treturn GetBytes(value, 4);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified 64-bit signed integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 8.</returns>\n\t\tpublic byte[] GetBytes(long value)\n\t\t{\n\t\t\treturn GetBytes(value, 8);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified single-precision floating point value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 4.</returns>\n\t\tpublic byte[] GetBytes(float value)\n\t\t{\n\t\t\treturn GetBytes(SingleToInt32Bits(value), 4);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified 16-bit unsigned integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 2.</returns>\n\t\tpublic byte[] GetBytes(ushort value)\n\t\t{\n\t\t\treturn GetBytes(value, 2);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified 32-bit unsigned integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 4.</returns>\n\t\tpublic byte[] GetBytes(uint value)\n\t\t{\n\t\t\treturn GetBytes(value, 4);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns the specified 64-bit unsigned integer value as an array of bytes.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <returns>An array of bytes with length 8.</returns>\n\t\tpublic byte[] GetBytes(ulong value)\n\t\t{\n\t\t\treturn GetBytes(unchecked((long) value), 8);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region CopyBytes conversions\n\n\t\t/// <summary>\n\t\t///     Copies the given number of bytes from the least-specific\n\t\t///     end of the specified value into the specified byte array, beginning\n\t\t///     at the specified index.\n\t\t///     This is used to implement the other CopyBytes methods.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy bytes for</param>\n\t\t/// <param name=\"bytes\">The number of significant bytes to copy</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tprivate void CopyBytes(long value, int bytes, byte[] buffer, int index)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(\"buffer\", \"Byte array must not be null\");\n\t\t\t}\n\t\t\tif (buffer.Length < index + bytes)\n\t\t\t{\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"Buffer not big enough for value\");\n\t\t\t}\n\t\t\tCopyBytesImpl(value, bytes, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the given number of bytes from the least-specific\n\t\t///     end of the specified value into the specified byte array, beginning\n\t\t///     at the specified index.\n\t\t///     This must be implemented in concrete derived classes, but the implementation\n\t\t///     may assume that the value will fit into the buffer.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy bytes for</param>\n\t\t/// <param name=\"bytes\">The number of significant bytes to copy</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tprotected abstract void CopyBytesImpl(long value, int bytes, byte[] buffer, int index);\n\n\t\t/// <summary>\n\t\t///     Copies the specified Boolean value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A Boolean value.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(bool value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value ? 1 : 0, 1, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified Unicode character value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">A character to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(char value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 2, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified double-precision floating point value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(double value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(DoubleToInt64Bits(value), 8, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified 16-bit signed integer value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(short value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 2, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified 32-bit signed integer value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(int value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 4, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified 64-bit signed integer value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(long value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 8, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified single-precision floating point value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(float value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(SingleToInt32Bits(value), 4, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified 16-bit unsigned integer value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(ushort value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 2, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified 32-bit unsigned integer value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(uint value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(value, 4, buffer, index);\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified 64-bit unsigned integer value into the specified byte array,\n\t\t///     beginning at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The number to convert.</param>\n\t\t/// <param name=\"buffer\">The byte array to copy the bytes into</param>\n\t\t/// <param name=\"index\">The first index into the array to copy the bytes into</param>\n\t\tpublic void CopyBytes(ulong value, byte[] buffer, int index)\n\t\t{\n\t\t\tCopyBytes(unchecked((long) value), 8, buffer, index);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Private struct used for Single/Int32 conversions\n\n\t\t/// <summary>\n\t\t///     Union used solely for the equivalent of DoubleToInt64Bits and vice versa.\n\t\t/// </summary>\n\t\t[StructLayout(LayoutKind.Explicit)]\n\t\tprivate struct Int32SingleUnion\n\t\t{\n\t\t\t/// <summary>\n\t\t\t///     Int32 version of the value.\n\t\t\t/// </summary>\n\t\t\t[FieldOffset(0)] private readonly int i;\n\n\t\t\t/// <summary>\n\t\t\t///     Single version of the value.\n\t\t\t/// </summary>\n\t\t\t[FieldOffset(0)] private readonly float f;\n\n\t\t\t/// <summary>\n\t\t\t///     Creates an instance representing the given integer.\n\t\t\t/// </summary>\n\t\t\t/// <param name=\"i\">The integer value of the new instance.</param>\n\t\t\tinternal Int32SingleUnion(int i)\n\t\t\t{\n\t\t\t\tthis.f = 0; // Just to keep the compiler happy\n\t\t\t\tthis.i = i;\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t///     Creates an instance representing the given floating point number.\n\t\t\t/// </summary>\n\t\t\t/// <param name=\"f\">The floating point value of the new instance.</param>\n\t\t\tinternal Int32SingleUnion(float f)\n\t\t\t{\n\t\t\t\tthis.i = 0; // Just to keep the compiler happy\n\t\t\t\tthis.f = f;\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t///     Returns the value of the instance as an integer.\n\t\t\t/// </summary>\n\t\t\tinternal int AsInt32\n\t\t\t{\n\t\t\t\tget { return i; }\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t///     Returns the value of the instance as a floating point number.\n\t\t\t/// </summary>\n\t\t\tinternal float AsSingle\n\t\t\t{\n\t\t\t\tget { return f; }\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/EndianBitConverter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 8475bccc39284c8d88906b7f019de0e6\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/Endianness.cs",
    "content": "//\n/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see\nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse\nor promote products derived from this software without prior written\npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called\n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n*/\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t/// <summary>\n\t///     Endianness of a converter\n\t/// </summary>\n\tpublic enum Endianness\n\t{\n\t\t/// <summary>\n\t\t///     Little endian - least significant byte first\n\t\t/// </summary>\n\t\tLittleEndian,\n\n\t\t/// <summary>\n\t\t///     Big endian - most significant byte first\n\t\t/// </summary>\n\t\tBigEndian\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/Endianness.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: e6d5923b4a01463885f062f2f8afa1ad\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/LittleEndianBitConverter.cs",
    "content": "//\n/*\n\"Miscellaneous Utility Library\" Software Licence\n\nVersion 1.0\n\nCopyright (c) 2004-2008 Jon Skeet and Marc Gravell.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. The end-user documentation included with the redistribution, if\nany, must include the following acknowledgment:\n\n\"This product includes software developed by Jon Skeet\nand Marc Gravell. Contact skeet@pobox.com, or see\nhttp://www.pobox.com/~skeet/).\"\n\nAlternately, this acknowledgment may appear in the software itself,\nif and wherever such third-party acknowledgments normally appear.\n\n4. The name \"Miscellaneous Utility Library\" must not be used to endorse\nor promote products derived from this software without prior written\npermission. For written permission, please contact skeet@pobox.com.\n\n5. Products derived from this software may not be called\n\"Miscellaneous Utility Library\", nor may \"Miscellaneous Utility Library\"\nappear in their name, without prior written permission of Jon Skeet.\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL JON SKEET BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n*/\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t/// <summary>\n\t///     Implementation of EndianBitConverter which converts to/from little-endian\n\t///     byte arrays.\n\t/// </summary>\n\tinternal sealed class LittleEndianBitConverter : EndianBitConverter\n\t{\n\t\t/// <summary>\n\t\t///     Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t///     Different computer architectures store data using different byte orders. \"Big-endian\"\n\t\t///     means the most significant byte is on the left end of a word. \"Little-endian\" means the\n\t\t///     most significant byte is on the right end of a word.\n\t\t/// </remarks>\n\t\t/// <returns>true if this converter is little-endian, false otherwise.</returns>\n\t\tpublic override sealed bool IsLittleEndian()\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Indicates the byte order (\"endianess\") in which data is converted using this class.\n\t\t/// </summary>\n\t\tpublic override sealed Endianness Endianness\n\t\t{\n\t\t\tget { return Endianness.LittleEndian; }\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Copies the specified number of bytes from value to buffer, starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to copy</param>\n\t\t/// <param name=\"bytes\">The number of bytes to copy</param>\n\t\t/// <param name=\"buffer\">The buffer to copy the bytes into</param>\n\t\t/// <param name=\"index\">The index to start at</param>\n\t\tprotected override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)\n\t\t{\n\t\t\tfor (var i = 0; i < bytes; i++)\n\t\t\t{\n\t\t\t\tbuffer[i + index] = unchecked((byte) (value & 0xff));\n\t\t\t\tvalue = value >> 8;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///     Returns a value built from the specified number of bytes from the given buffer,\n\t\t///     starting at index.\n\t\t/// </summary>\n\t\t/// <param name=\"buffer\">The data in byte array format</param>\n\t\t/// <param name=\"startIndex\">The first index to use</param>\n\t\t/// <param name=\"bytesToConvert\">The number of bytes to use</param>\n\t\t/// <returns>The value built from the given bytes</returns>\n\t\tprotected override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)\n\t\t{\n\t\t\tlong ret = 0;\n\t\t\tfor (var i = 0; i < bytesToConvert; i++)\n\t\t\t{\n\t\t\t\tret = unchecked((ret << 8) | buffer[startIndex + bytesToConvert - 1 - i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/LittleEndianBitConverter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: b48cfd0cc76d4563871e82c7d7a65db3\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackExtensionType.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing GameDevWare.Serialization.Serializers;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t/// <summary>\n\t///     Representation of extension types in Message Pack. This type is immutable by design\n\t/// </summary>\n\t[TypeSerializer(typeof(MsgPackExtensionTypeSerializer))]\n\tpublic sealed class MessagePackExtensionType : IEquatable<MessagePackExtensionType>, IComparable, IComparable<MessagePackExtensionType>\n\t{\n\t\tprivate static readonly byte[] EmptyBytes = new byte[0];\n\n\t\tprivate readonly ArraySegment<byte> data;\n\t\tprivate readonly int hashCode;\n\n\t\tpublic int Length\n\t\t{\n\t\t\tget { return this.data.Count; }\n\t\t}\n\t\tpublic sbyte Type { get; private set; }\n\n\t\t// ReSharper disable PossibleNullReferenceException\n\t\tpublic byte this[int index]\n\t\t{\n\t\t\tget { return this.data.Array[this.data.Offset + index]; }\n\t\t}\n\n\t\t// ReSharper restore PossibleNullReferenceException\n\n\t\tpublic MessagePackExtensionType()\n\t\t{\n\t\t\tthis.Type = 0; // generic binary\n\t\t\tthis.data = new ArraySegment<byte>(EmptyBytes, 0, 0);\n\t\t}\n\t\tpublic MessagePackExtensionType(byte[] binaryData)\n\t\t\t: this(0, binaryData) { }\n\t\tpublic MessagePackExtensionType(sbyte type, byte[] binaryData)\n\t\t\t: this(type, new ArraySegment<byte>(binaryData, 0, binaryData.Length))\n\t\t{\n\t\t}\n\t\tpublic MessagePackExtensionType(sbyte type, ArraySegment<byte> binaryData)\n\t\t{\n\t\t\tif (binaryData.Array == null) throw new ArgumentNullException(\"binaryData\");\n\n\t\t\tthis.data = binaryData;\n\t\t\tthis.Type = type;\n\n\t\t\tvar buffer = this.data.Array ?? EmptyBytes;\n\t\t\tif (this.data.Count >= 4)\n\t\t\t{\n\t\t\t\tthis.hashCode = unchecked(this.data.Count * 17 + BitConverter.ToInt32(buffer, this.data.Offset));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.hashCode = this.data.Count;\n\t\t\t\tfor (var i = this.data.Offset; i < this.data.Offset + this.data.Count; i++)\n\t\t\t\t\tthis.hashCode += unchecked(buffer[i] * 114);\n\t\t\t}\n\t\t}\n\n\t\tpublic void CopyTo(byte[] destination, int index, int bytesToCopy)\n\t\t{\n\t\t\tBuffer.BlockCopy(this.data.Array ?? EmptyBytes, this.data.Offset, destination, index, Math.Min(bytesToCopy, this.Length));\n\t\t}\n\t\tpublic byte[] ToByteArray()\n\t\t{\n\t\t\tif (this.data.Offset != 0 || this.Length != this.data.Count)\n\t\t\t{\n\t\t\t\tvar byteArray = new byte[this.Length];\n\t\t\t\tBuffer.BlockCopy(this.data.Array ?? EmptyBytes, this.data.Offset, byteArray, 0, byteArray.Length);\n\t\t\t\treturn byteArray;\n\t\t\t}\n\n\t\t\treturn this.data.Array;\n\t\t}\n\t\tpublic ArraySegment<byte> ToArraySegment()\n\t\t{\n\t\t\treturn this.data;\n\t\t}\n\t\tpublic string ToBase64()\n\t\t{\n\t\t\treturn Convert.ToBase64String(this.data.Array ?? EmptyBytes, this.data.Offset, this.Length);\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\treturn this.Equals(obj as MessagePackExtensionType);\n\t\t}\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn this.hashCode;\n\t\t}\n\n\t\tpublic bool Equals(MessagePackExtensionType other)\n\t\t{\n\t\t\tif (other == null) return false;\n\t\t\tif (ReferenceEquals(this, other)) return true;\n\n\t\t\tif (this.Length != other.Length) return false;\n\t\t\tif (this.GetHashCode() != other.GetHashCode()) return false;\n\n\t\t\tfor (var i = 0; i < this.Length; i++)\n\t\t\t{\n\t\t\t\tif (this[i] != other[i]) return false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t\tpublic int CompareTo(object obj)\n\t\t{\n\t\t\treturn this.CompareTo(obj as MessagePackExtensionType);\n\t\t}\n\t\tpublic int CompareTo(MessagePackExtensionType other)\n\t\t{\n\t\t\tif (other == null) return 1;\n\n\t\t\t// wee need to align buffers with different sizes\n\t\t\tfor (int i = 0, j = 0; i < this.Length || j < other.Length; i++, j++)\n\t\t\t{\n\t\t\t\t// we need offsets\n\t\t\t\tvar io = this.Length - other.Length;\n\t\t\t\tvar jo = other.Length - this.Length;\n\n\t\t\t\t// only negative offset is needed\n\t\t\t\tif (io > 0) io = 0;\n\t\t\t\tif (jo > 0) jo = 0;\n\n\t\t\t\t// get bytes with offsets\n\t\t\t\tvar ib = i + io >= 0 ? this[i + io] : (byte)0;\n\t\t\t\tvar jb = j + jo >= 0 ? other[j + jo] : (byte)0;\n\n\t\t\t\t// compare\n\t\t\t\tif (ib > jb) return 1;\n\n\t\t\t\tif (jb > ib) return -1;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic static bool operator ==(MessagePackExtensionType a, MessagePackExtensionType b)\n\t\t{\n\t\t\tif (ReferenceEquals(a, null) && ReferenceEquals(b, null)) return false;\n\t\t\tif (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return false;\n\n\t\t\treturn a.Equals(b);\n\t\t}\n\t\tpublic static bool operator !=(MessagePackExtensionType a, MessagePackExtensionType b)\n\t\t{\n\t\t\treturn !(a == b);\n\t\t}\n\n\t\tpublic static explicit operator byte[] (MessagePackExtensionType messagePackExtension)\n\t\t{\n\t\t\tif (messagePackExtension != null)\n\t\t\t\treturn messagePackExtension.ToByteArray();\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\t\tpublic static explicit operator ArraySegment<byte>(MessagePackExtensionType messagePackExtension)\n\t\t{\n\t\t\tif (messagePackExtension == null) throw new ArgumentNullException(\"messagePackExtension\");\n\t\t\treturn messagePackExtension.ToArraySegment();\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn Convert.ToBase64String(this.data.Array ?? EmptyBytes, this.data.Offset, Math.Min(this.Length, 64)) + ( this.Length > 64 ? \"...\" : \"\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackExtensionType.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: fc357227a2b747739e24bfde7cc369fe\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackExtensionTypeHandler.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\tpublic abstract class MessagePackExtensionTypeHandler\n\t{\n\t\tpublic abstract IEnumerable<Type> ExtensionTypes { get; }\n\n\t\tpublic abstract bool TryRead(sbyte type, ArraySegment<byte> data, out object value);\n\t\tpublic abstract bool TryWrite(object value, out sbyte type, ref ArraySegment<byte> data);\n\n\t\t/// <inheritdoc />\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"Extension Types: {0}\", string.Join(\", \", this.ExtensionTypes.Select(t => t.ToString()).ToArray()));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackExtensionTypeHandler.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 88fe3b8c87c14c01979834465a77bdd4\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackReader.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\tpublic class MsgPackReader : IJsonReader\n\t{\n\t\tpublic const int DEFAULT_BUFFER_SIZE = 1024 * 8;\n\n\t\tprivate static readonly object TrueObject = true;\n\t\tprivate static readonly object FalseObject = false;\n\n\t\tinternal class MsgPackValueInfo : IValueInfo\n\t\t{\n\t\t\tprivate readonly MsgPackReader reader;\n\t\t\tprivate object value;\n\n\t\t\tinternal MsgPackValueInfo(MsgPackReader reader)\n\t\t\t{\n\t\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\t\tthis.reader = reader;\n\t\t\t}\n\n\t\t\tpublic JsonToken Token { get; private set; }\n\t\t\tpublic bool HasValue { get; private set; }\n\t\t\tpublic object Raw\n\t\t\t{\n\t\t\t\tget { return this.value; }\n\t\t\t\tset\n\t\t\t\t{\n\t\t\t\t\tthis.value = value;\n\t\t\t\t\tthis.HasValue = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic Type Type\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tif (this.HasValue && this.value != null)\n\t\t\t\t\t\treturn this.value.GetType();\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (this.Token)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase JsonToken.BeginArray:\n\t\t\t\t\t\t\t\treturn typeof(List<object>);\n\t\t\t\t\t\t\tcase JsonToken.Number:\n\t\t\t\t\t\t\t\treturn typeof(double);\n\t\t\t\t\t\t\tcase JsonToken.Member:\n\t\t\t\t\t\t\tcase JsonToken.StringLiteral:\n\t\t\t\t\t\t\t\treturn typeof(string);\n\t\t\t\t\t\t\tcase JsonToken.DateTime:\n\t\t\t\t\t\t\t\treturn typeof(DateTime);\n\t\t\t\t\t\t\tcase JsonToken.Boolean:\n\t\t\t\t\t\t\t\treturn typeof(bool);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn typeof(object);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic int LineNumber { get { return 0; } }\n\t\t\tpublic int ColumnNumber { get; private set; }\n\t\t\tpublic bool AsBoolean { get { return Convert.ToBoolean(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic byte AsByte { get { return Convert.ToByte(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic short AsInt16 { get { return Convert.ToInt16(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic int AsInt32 { get { return Convert.ToInt32(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic long AsInt64 { get { return Convert.ToInt64(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic sbyte AsSByte { get { return Convert.ToSByte(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic ushort AsUInt16 { get { return Convert.ToUInt16(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic uint AsUInt32 { get { return Convert.ToUInt32(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic ulong AsUInt64 { get { return Convert.ToUInt64(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic float AsSingle { get { return Convert.ToSingle(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic double AsDouble { get { return Convert.ToDouble(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic decimal AsDecimal { get { return Convert.ToDecimal(this.Raw, this.reader.Context.Format); } }\n\t\t\tpublic DateTime AsDateTime\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tif (this.Raw is DateTime)\n\t\t\t\t\t\treturn (DateTime)this.Raw;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn DateTime.ParseExact(this.AsString, this.reader.Context.DateTimeFormats, this.reader.Context.Format,\n\t\t\t\t\t\t\tDateTimeStyles.AssumeUniversal);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic string AsString\n\t\t\t{\n\t\t\t\tget\n\t\t\t\t{\n\t\t\t\t\tvar raw = this.Raw;\n\t\t\t\t\tif (raw is string)\n\t\t\t\t\t\treturn (string)raw;\n\t\t\t\t\telse if (raw is byte[])\n\t\t\t\t\t\treturn Convert.ToBase64String((byte[])raw);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn Convert.ToString(raw, this.reader.Context.Format);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthis.value = null;\n\t\t\t\tthis.HasValue = false;\n\t\t\t\tthis.Token = JsonToken.None;\n\t\t\t\tthis.ColumnNumber = 0;\n\t\t\t}\n\t\t\tpublic void SetValue(object rawValue, JsonToken token, int position)\n\t\t\t{\n\t\t\t\tthis.HasValue = token == JsonToken.Boolean || token == JsonToken.DateTime ||\n\t\t\t\t\ttoken == JsonToken.Member || token == JsonToken.Null ||\n\t\t\t\t\ttoken == JsonToken.Number || token == JsonToken.StringLiteral;\n\t\t\t\tthis.value = rawValue;\n\t\t\t\tthis.Token = token;\n\t\t\t\tthis.ColumnNumber = position;\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\tif (this.HasValue)\n\t\t\t\t\treturn Convert.ToString(this.value);\n\t\t\t\telse\n\t\t\t\t\treturn \"<no value>\";\n\t\t\t}\n\t\t}\n\t\tinternal struct ClosingToken\n\t\t{\n\t\t\tpublic JsonToken Token;\n\t\t\tpublic long Counter;\n\t\t}\n\n\t\tprivate readonly Stream inputStream;\n\t\tprivate readonly byte[] buffer;\n\t\tprivate readonly EndianBitConverter bitConverter;\n\t\tprivate readonly Stack<ClosingToken> closingTokens;\n\t\tprivate int bufferOffset;\n\t\tprivate int bufferRead;\n\t\tprivate int bufferAvailable;\n\t\tprivate bool isEndOfStream;\n\t\tprivate int totalBytesRead;\n\n\t\tpublic SerializationContext Context { get; private set; }\n\t\tJsonToken IJsonReader.Token\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (this.Value.Token == JsonToken.None)\n\t\t\t\t\tthis.NextToken();\n\t\t\t\tif (this.isEndOfStream)\n\t\t\t\t\treturn JsonToken.EndOfStream;\n\n\t\t\t\treturn this.Value.Token;\n\t\t\t}\n\t\t}\n\t\tobject IJsonReader.RawValue\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (this.Value.Token == JsonToken.None)\n\t\t\t\t\tthis.NextToken();\n\n\t\t\t\treturn this.Value.Raw;\n\t\t\t}\n\t\t}\n\t\tIValueInfo IJsonReader.Value\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (this.Value.Token == JsonToken.None)\n\t\t\t\t\tthis.NextToken();\n\n\t\t\t\treturn this.Value;\n\t\t\t}\n\t\t}\n\t\tinternal MsgPackValueInfo Value { get; private set; }\n\n\t\tpublic MsgPackReader(Stream stream, SerializationContext context, Endianness endianness = Endianness.BigEndian, byte[] buffer = null)\n\t\t{\n\t\t\tif (stream == null) throw new ArgumentNullException(\"stream\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (!stream.CanRead) throw JsonSerializationException.StreamIsNotReadable();\n\t\t\tif (buffer != null && buffer.Length < 1024) throw new ArgumentOutOfRangeException(\"buffer\", \"Buffer should be at least 1024 bytes long.\");\n\n\t\t\tthis.Context = context;\n\t\t\tthis.inputStream = stream;\n\t\t\tthis.buffer = buffer ?? new byte[DEFAULT_BUFFER_SIZE];\n\t\t\tthis.bufferOffset = 0;\n\t\t\tthis.bufferRead = 0;\n\t\t\tthis.bufferAvailable = 0;\n\t\t\tthis.bitConverter = endianness == Endianness.BigEndian ? EndianBitConverter.Big : (EndianBitConverter)EndianBitConverter.Little;\n\t\t\tthis.closingTokens = new Stack<ClosingToken>();\n\n\t\t\tthis.Value = new MsgPackValueInfo(this);\n\t\t}\n\n\t\tpublic bool NextToken()\n\t\t{\n\t\t\tthis.Value.Reset();\n\n\t\t\tif (this.closingTokens.Count > 0 && this.closingTokens.Peek().Counter == 0)\n\t\t\t{\n\t\t\t\tvar closingToken = this.closingTokens.Pop();\n\t\t\t\tthis.Value.SetValue(null, closingToken.Token, this.totalBytesRead);\n\n\t\t\t\tthis.DecrementClosingTokenCounter();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!this.ReadToBuffer(1, throwOnEos: false))\n\t\t\t{\n\t\t\t\tthis.isEndOfStream = true;\n\t\t\t\tthis.Value.SetValue(null, JsonToken.EndOfStream, this.totalBytesRead);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar pos = this.totalBytesRead;\n\t\t\tvar formatValue = this.buffer[this.bufferOffset];\n\t\t\tif (formatValue >= (byte)MsgPackType.FixArrayStart && formatValue <= (byte)MsgPackType.FixArrayEnd)\n\t\t\t{\n\t\t\t\tvar arrayCount = formatValue - (byte)MsgPackType.FixArrayStart;\n\n\t\t\t\tthis.closingTokens.Push(new ClosingToken { Token = JsonToken.EndOfArray, Counter = arrayCount + 1 });\n\t\t\t\tthis.Value.SetValue(null, JsonToken.BeginArray, pos);\n\t\t\t}\n\t\t\telse if (formatValue >= (byte)MsgPackType.FixStrStart && formatValue <= (byte)MsgPackType.FixStrEnd)\n\t\t\t{\n\t\t\t\tvar strCount = formatValue - (byte)MsgPackType.FixStrStart;\n\t\t\t\tvar strBytes = this.ReadBytes(strCount);\n\t\t\t\tvar strValue = this.Context.Encoding.GetString(strBytes.Array, strBytes.Offset, strBytes.Count);\n\n\t\t\t\tvar strTokenType = JsonToken.StringLiteral;\n\t\t\t\tif (this.closingTokens.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tvar closingToken = this.closingTokens.Peek();\n\t\t\t\t\tif (closingToken.Token == JsonToken.EndOfObject && closingToken.Counter > 0 && closingToken.Counter % 2 == 0)\n\t\t\t\t\t\tstrTokenType = JsonToken.Member;\n\t\t\t\t}\n\t\t\t\tthis.Value.SetValue(strValue, strTokenType, pos);\n\t\t\t}\n\t\t\telse if (formatValue >= (byte)MsgPackType.FixMapStart && formatValue <= (byte)MsgPackType.FixMapEnd)\n\t\t\t{\n\t\t\t\tvar mapCount = formatValue - (byte)MsgPackType.FixMapStart;\n\t\t\t\tthis.closingTokens.Push(new ClosingToken { Token = JsonToken.EndOfObject, Counter = mapCount * 2 + 1 });\n\t\t\t\tthis.Value.SetValue(null, JsonToken.BeginObject, pos);\n\t\t\t}\n\t\t\telse if (formatValue >= (byte)MsgPackType.NegativeFixIntStart)\n\t\t\t{\n\t\t\t\tvar value = unchecked((sbyte)formatValue);\n\t\t\t\tthis.Value.SetValue(value, JsonToken.Number, pos);\n\t\t\t}\n\t\t\telse if (formatValue <= (byte)MsgPackType.PositiveFixIntEnd)\n\t\t\t{\n\t\t\t\tvar value = unchecked((byte)formatValue);\n\t\t\t\tthis.Value.SetValue(value, JsonToken.Number, pos);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tswitch ((MsgPackType)formatValue)\n\t\t\t\t{\n\t\t\t\t\tcase MsgPackType.Nil:\n\t\t\t\t\t\tthis.Value.SetValue(null, JsonToken.Null, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Array16:\n\t\t\t\t\tcase MsgPackType.Array32:\n\t\t\t\t\t\tvar arrayCount = 0L;\n\t\t\t\t\t\tif (formatValue == (int)MsgPackType.Array16)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\t\tarrayCount = this.bitConverter.ToUInt16(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Array32)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\t\tarrayCount = this.bitConverter.ToUInt32(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.closingTokens.Push(new ClosingToken { Token = JsonToken.EndOfArray, Counter = arrayCount + 1 });\n\t\t\t\t\t\tthis.Value.SetValue(null, JsonToken.BeginArray, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Map16:\n\t\t\t\t\tcase MsgPackType.Map32:\n\t\t\t\t\t\tvar mapCount = 0L;\n\t\t\t\t\t\tif (formatValue == (int)MsgPackType.Map16)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\t\tmapCount = this.bitConverter.ToUInt16(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Map32)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\t\tmapCount = this.bitConverter.ToUInt32(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.closingTokens.Push(new ClosingToken { Token = JsonToken.EndOfObject, Counter = mapCount * 2 + 1 });\n\t\t\t\t\t\tthis.Value.SetValue(null, JsonToken.BeginObject, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Str16:\n\t\t\t\t\tcase MsgPackType.Str32:\n\t\t\t\t\tcase MsgPackType.Str8:\n\t\t\t\t\t\tvar strBytesCount = 0L;\n\t\t\t\t\t\tif (formatValue == (int)MsgPackType.Str8)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(1, throwOnEos: true);\n\t\t\t\t\t\t\tstrBytesCount = this.buffer[this.bufferOffset];\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Str16)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\t\tstrBytesCount = this.bitConverter.ToUInt16(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Str32)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\t\tstrBytesCount = this.bitConverter.ToUInt32(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar strTokenType = JsonToken.StringLiteral;\n\t\t\t\t\t\tif (this.closingTokens.Count > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar closingToken = this.closingTokens.Peek();\n\t\t\t\t\t\t\tif (closingToken.Token == JsonToken.EndOfObject && closingToken.Counter > 0 && closingToken.Counter % 2 == 0)\n\t\t\t\t\t\t\t\tstrTokenType = JsonToken.Member;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar strBytes = this.ReadBytes(strBytesCount);\n\t\t\t\t\t\tvar strValue = this.Context.Encoding.GetString(strBytes.Array, strBytes.Offset, strBytes.Count);\n\t\t\t\t\t\tthis.Value.SetValue(strValue, strTokenType, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Bin32:\n\t\t\t\t\tcase MsgPackType.Bin16:\n\t\t\t\t\tcase MsgPackType.Bin8:\n\t\t\t\t\t\tvar bytesCount = 0L;\n\t\t\t\t\t\tif (formatValue == (int)MsgPackType.Bin8)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(1, throwOnEos: true);\n\t\t\t\t\t\t\tbytesCount = this.buffer[this.bufferOffset];\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Bin16)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\t\tbytesCount = this.bitConverter.ToUInt16(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Bin32)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\t\tbytesCount = this.bitConverter.ToUInt32(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar bytes = this.ReadBytes(bytesCount, forceNewBuffer: true);\n\t\t\t\t\t\tthis.Value.SetValue(bytes.Array, JsonToken.StringLiteral, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.FixExt1:\n\t\t\t\t\tcase MsgPackType.FixExt16:\n\t\t\t\t\tcase MsgPackType.FixExt2:\n\t\t\t\t\tcase MsgPackType.FixExt4:\n\t\t\t\t\tcase MsgPackType.FixExt8:\n\t\t\t\t\tcase MsgPackType.Ext32:\n\t\t\t\t\tcase MsgPackType.Ext16:\n\t\t\t\t\tcase MsgPackType.Ext8:\n\t\t\t\t\t\tvar dataCount = 0L;\n\t\t\t\t\t\tif (formatValue == (int)MsgPackType.FixExt1)\n\t\t\t\t\t\t\tdataCount = 1;\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.FixExt2)\n\t\t\t\t\t\t\tdataCount = 2;\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.FixExt4)\n\t\t\t\t\t\t\tdataCount = 4;\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.FixExt8)\n\t\t\t\t\t\t\tdataCount = 8;\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.FixExt16)\n\t\t\t\t\t\t\tdataCount = 16;\n\t\t\t\t\t\tif (formatValue == (int)MsgPackType.Ext8)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(1, throwOnEos: true);\n\t\t\t\t\t\t\tdataCount = this.buffer[this.bufferOffset];\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Ext16)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\t\tdataCount = this.bitConverter.ToUInt16(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (formatValue == (int)MsgPackType.Ext32)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\t\tdataCount = this.bitConverter.ToUInt32(this.buffer, this.bufferOffset);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.ReadToBuffer(1, true);\n\t\t\t\t\t\tvar extensionType = unchecked((sbyte)this.buffer[this.bufferOffset]);\n\n\t\t\t\t\t\tvar data = this.ReadBytes(dataCount);\n\t\t\t\t\t\tthis.Value.SetValue(this.ReadExtensionType(extensionType, data), JsonToken.StringLiteral, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.False:\n\t\t\t\t\t\tthis.Value.SetValue(FalseObject, JsonToken.Boolean, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.True:\n\t\t\t\t\t\tthis.Value.SetValue(TrueObject, JsonToken.Boolean, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Float32:\n\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToSingle(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Float64:\n\t\t\t\t\t\tthis.ReadToBuffer(8, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToDouble(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Int8:\n\t\t\t\t\t\tthis.ReadToBuffer(1, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(unchecked((sbyte)this.buffer[this.bufferOffset]), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Int16:\n\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToInt16(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Int32:\n\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToInt32(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.Int64:\n\t\t\t\t\t\tthis.ReadToBuffer(8, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToInt64(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.UInt8:\n\t\t\t\t\t\tthis.ReadToBuffer(1, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.buffer[this.bufferOffset], JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.UInt16:\n\t\t\t\t\t\tthis.ReadToBuffer(2, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToUInt16(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.UInt32:\n\t\t\t\t\t\tthis.ReadToBuffer(4, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToUInt32(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.UInt64:\n\t\t\t\t\t\tthis.ReadToBuffer(8, throwOnEos: true);\n\t\t\t\t\t\tthis.Value.SetValue(this.bitConverter.ToUInt64(this.buffer, this.bufferOffset), JsonToken.Number, pos);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MsgPackType.PositiveFixIntStart:\n\t\t\t\t\tcase MsgPackType.PositiveFixIntEnd:\n\t\t\t\t\tcase MsgPackType.FixMapStart:\n\t\t\t\t\tcase MsgPackType.FixMapEnd:\n\t\t\t\t\tcase MsgPackType.FixArrayStart:\n\t\t\t\t\tcase MsgPackType.FixArrayEnd:\n\t\t\t\t\tcase MsgPackType.FixStrStart:\n\t\t\t\t\tcase MsgPackType.FixStrEnd:\n\t\t\t\t\tcase MsgPackType.Unused:\n\t\t\t\t\tcase MsgPackType.NegativeFixIntStart:\n\t\t\t\t\tcase MsgPackType.NegativeFixIntEnd:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new UnknownMsgPackFormatException(formatValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.DecrementClosingTokenCounter();\n\n\t\t\treturn true;\n\t\t}\n\t\tpublic void Reset()\n\t\t{\n\t\t\tArray.Clear(this.buffer, 0, this.buffer.Length);\n\t\t\tthis.bufferOffset = 0;\n\t\t\tthis.bufferAvailable = 0;\n\t\t\tthis.bufferRead = 0;\n\t\t\tthis.totalBytesRead = 0;\n\t\t\tthis.Value.Reset();\n\t\t}\n\t\tpublic bool IsEndOfStream()\n\t\t{\n\t\t\treturn this.isEndOfStream;\n\t\t}\n\n\t\tprivate bool ReadToBuffer(int bytesRequired, bool throwOnEos)\n\t\t{\n\t\t\tthis.bufferAvailable -= this.bufferRead;\n\t\t\tthis.bufferOffset += this.bufferRead;\n\t\t\tthis.bufferRead = 0;\n\n\t\t\tif (this.bufferAvailable < bytesRequired)\n\t\t\t{\n\t\t\t\tif (this.bufferAvailable > 0)\n\t\t\t\t\tBuffer.BlockCopy(this.buffer, this.bufferOffset, this.buffer, 0, this.bufferAvailable);\n\n\t\t\t\tthis.bufferOffset = 0;\n\t\t\t\twhile (this.bufferAvailable < bytesRequired)\n\t\t\t\t{\n\t\t\t\t\tvar read = this.inputStream.Read(this.buffer, this.bufferAvailable, this.buffer.Length - this.bufferAvailable);\n\t\t\t\t\tthis.bufferAvailable += read;\n\n\t\t\t\t\tif (read != 0 || this.bufferAvailable >= bytesRequired)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tif (throwOnEos)\n\t\t\t\t\t\tthrow JsonSerializationException.UnexpectedEndOfStream(this);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.bufferRead = bytesRequired;\n\t\t\tthis.totalBytesRead += bytesRequired;\n\t\t\treturn true;\n\t\t}\n\t\tprivate ArraySegment<byte> ReadBytes(long bytesRequired, bool forceNewBuffer = false)\n\t\t{\n\t\t\tif (bytesRequired > int.MaxValue) throw new ArgumentOutOfRangeException(\"bytesRequired\");\n\n\t\t\tthis.bufferAvailable -= this.bufferRead;\n\t\t\tthis.bufferOffset += this.bufferRead;\n\t\t\tthis.bufferRead = 0;\n\n\t\t\tif (this.bufferAvailable >= bytesRequired && !forceNewBuffer)\n\t\t\t{\n\t\t\t\tvar bytes = new ArraySegment<byte>(this.buffer, this.bufferOffset, (int)bytesRequired);\n\n\t\t\t\tthis.bufferAvailable -= (int)bytesRequired;\n\t\t\t\tthis.bufferOffset += (int)bytesRequired;\n\t\t\t\tthis.totalBytesRead += (int)bytesRequired;\n\n\t\t\t\treturn bytes;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar bytes = new byte[bytesRequired];\n\t\t\t\tvar bytesOffset = 0;\n\t\t\t\tif (this.bufferAvailable > 0 && bytesOffset < bytes.Length)\n\t\t\t\t{\n\t\t\t\t\tvar bytesToCopy = Math.Min(bytes.Length - bytesOffset, this.bufferAvailable);\n\t\t\t\t\tBuffer.BlockCopy(this.buffer, this.bufferOffset, bytes, bytesOffset, bytesToCopy);\n\n\t\t\t\t\tbytesOffset += bytesToCopy;\n\t\t\t\t\tthis.bufferOffset += bytesToCopy;\n\n\t\t\t\t\tthis.bufferAvailable -= bytesToCopy;\n\t\t\t\t\tthis.totalBytesRead += bytesToCopy;\n\t\t\t\t}\n\n\t\t\t\tif (this.bufferAvailable == 0)\n\t\t\t\t\tthis.bufferOffset = 0;\n\n\t\t\t\twhile (bytesOffset < bytes.Length)\n\t\t\t\t{\n\t\t\t\t\tvar read = this.inputStream.Read(bytes, bytesOffset, bytes.Length - bytesOffset);\n\n\t\t\t\t\tbytesOffset += read;\n\t\t\t\t\tthis.totalBytesRead += read;\n\n\t\t\t\t\tif (read == 0 && bytesOffset < bytes.Length)\n\t\t\t\t\t\tthrow JsonSerializationException.UnexpectedEndOfStream(this);\n\t\t\t\t}\n\n\t\t\t\treturn new ArraySegment<byte>(bytes, 0, bytes.Length);\n\t\t\t}\n\t\t}\n\t\tprivate object ReadExtensionType(sbyte type, ArraySegment<byte> data)\n\t\t{\n\t\t\tvar value = default(object);\n\t\t\tif (this.Context.ExtensionTypeHandler.TryRead(type, data, out value))\n\t\t\t{\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (ReferenceEquals(data.Array, this.buffer))\n\t\t\t\t\tdata = new ArraySegment<byte>((byte[])data.Array.Clone(), data.Offset, data.Count);\n\n\t\t\t\treturn new MessagePackExtensionType(type, data);\n\t\t\t}\n\t\t}\n\n\t\tprivate void DecrementClosingTokenCounter()\n\t\t{\n\t\t\tif (this.closingTokens.Count > 0)\n\t\t\t{\n\t\t\t\tvar closingToken = this.closingTokens.Pop();\n\t\t\t\tclosingToken.Counter--;\n\t\t\t\tthis.closingTokens.Push(closingToken);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackReader.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 06480cbcfec44e6985c572e8f8c47f4d\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackTimestamp.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing GameDevWare.Serialization.Serializers;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t[TypeSerializer(typeof(MsgPackTimestampSerializer))]\n\tpublic struct MessagePackTimestamp : IEquatable<MessagePackTimestamp>, IComparable<MessagePackTimestamp>\n\t{\n\t\tpublic const int MAX_NANO_SECONDS = 999999999;\n\n\t\tpublic readonly long Seconds;\n\t\tpublic readonly uint NanoSeconds;\n\n\t\tpublic MessagePackTimestamp(long seconds, uint nanoSeconds)\n\t\t{\n\t\t\tif (nanoSeconds > MAX_NANO_SECONDS)\n\t\t\t\tnanoSeconds = MAX_NANO_SECONDS;\n\n\t\t\tthis.Seconds = seconds;\n\t\t\tthis.NanoSeconds = nanoSeconds;\n\t\t}\n\n\t\tpublic static explicit operator DateTime(MessagePackTimestamp timestamp)\n\t\t{\n\t\t\treturn new DateTime(JsonUtils.UnixEpochTicks + ((TimeSpan)timestamp).Ticks, DateTimeKind.Unspecified);\n\t\t}\n\t\tpublic static explicit operator TimeSpan(MessagePackTimestamp timestamp)\n\t\t{\n\t\t\treturn TimeSpan.FromSeconds(timestamp.Seconds) + TimeSpan.FromTicks(timestamp.NanoSeconds / 100);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn unchecked(this.Seconds.GetHashCode() * 17 + this.NanoSeconds.GetHashCode());\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is MessagePackTimestamp)\n\t\t\t\treturn this.Equals((MessagePackTimestamp)obj);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic bool Equals(MessagePackTimestamp other)\n\t\t{\n\t\t\treturn this.Seconds.Equals(other.Seconds) && this.NanoSeconds.Equals(other.NanoSeconds);\n\t\t}\n\t\t/// <inheritdoc />\n\t\tpublic int CompareTo(MessagePackTimestamp other)\n\t\t{\n\t\t\tvar cmp = this.Seconds.CompareTo(other.Seconds);\n\t\t\tif (cmp != 0)\n\t\t\t\treturn cmp;\n\t\t\treturn this.NanoSeconds.CompareTo(other.NanoSeconds);\n\t\t}\n\n\t\tpublic static bool operator >(MessagePackTimestamp a, MessagePackTimestamp b)\n\t\t{\n\t\t\treturn a.CompareTo(b) == 1;\n\t\t}\n\t\tpublic static bool operator <(MessagePackTimestamp a, MessagePackTimestamp b)\n\t\t{\n\t\t\treturn a.CompareTo(b) == -1;\n\t\t}\n\t\tpublic static bool operator >=(MessagePackTimestamp a, MessagePackTimestamp b)\n\t\t{\n\t\t\treturn a.CompareTo(b) != -1;\n\t\t}\n\t\tpublic static bool operator <=(MessagePackTimestamp a, MessagePackTimestamp b)\n\t\t{\n\t\t\treturn a.CompareTo(b) != 1;\n\t\t}\n\t\tpublic static bool operator ==(MessagePackTimestamp a, MessagePackTimestamp b)\n\t\t{\n\t\t\treturn a.Equals(b);\n\t\t}\n\t\tpublic static bool operator !=(MessagePackTimestamp a, MessagePackTimestamp b)\n\t\t{\n\t\t\treturn !a.Equals(b);\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"seconds: {0}, nanoseconds: {1}\", this.Seconds, this.NanoSeconds);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackTimestamp.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 075db24d85444948957bde92119a4fae\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackType.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\tpublic enum MsgPackType : byte\n\t{\n\t\tPositiveFixIntStart = 0x00,\n\t\tPositiveFixIntEnd = 0x7f,\n\t\tFixMapStart = 0x80,\n\t\tFixMapEnd = 0x8f,\n\t\tFixArrayStart = 0x90,\n\t\tFixArrayEnd = 0x9f,\n\t\tFixStrStart = 0xa0,\n\t\tFixStrEnd = 0xbf,\n\t\tNil = 0xc0,\n\t\tUnused = 0xc1,\n\t\tFalse = 0xc2,\n\t\tTrue = 0xc3,\n\t\tBin8 = 0xc4,\n\t\tBin16 = 0xc5,\n\t\tBin32 = 0xc6,\n\t\tExt8 = 0xc7,\n\t\tExt16 = 0xc8,\n\t\tExt32 = 0xc9,\n\t\tFloat32 = 0xca,\n\t\tFloat64 = 0xcb,\n\t\tUInt8 = 0xcc,\n\t\tUInt16 = 0xcd,\n\t\tUInt32 = 0xce,\n\t\tUInt64 = 0xcf,\n\t\tInt8 = 0xd0,\n\t\tInt16 = 0xd1,\n\t\tInt32 = 0xd2,\n\t\tInt64 = 0xd3,\n\t\tFixExt1 = 0xd4,\n\t\tFixExt2 = 0xd5,\n\t\tFixExt4 = 0xd6,\n\t\tFixExt8 = 0xd7,\n\t\tFixExt16 = 0xd8,\n\t\tStr8 = 0xd9,\n\t\tStr16 = 0xda,\n\t\tStr32 = 0xdb,\n\t\tArray16 = 0xdc,\n\t\tArray32 = 0xdd,\n\t\tMap16 = 0xde,\n\t\tMap32 = 0xdf,\n\t\tNegativeFixIntStart = 0xe0,\n\t\tNegativeFixIntEnd = 0xff\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackType.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: b16da3c0c31c473aac9e7e69102866c7\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackWriter.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.IO;\nusing System.Linq;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\tpublic class MsgPackWriter : IJsonWriter\n\t{\n\t\tpublic const int DEFAULT_BUFFER_SIZE = 32;\n\n\t\tprivate readonly SerializationContext context;\n\t\tprivate readonly Stream outputStream;\n\t\tprivate readonly byte[] buffer;\n\t\tprivate readonly EndianBitConverter bitConverter;\n\t\tprivate long bytesWritten;\n\n\t\tpublic MsgPackWriter(Stream stream, SerializationContext context, byte[] buffer = null)\n\t\t{\n\t\t\tif (stream == null) throw new ArgumentNullException(\"stream\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (!stream.CanWrite) throw JsonSerializationException.StreamIsNotReadable();\n\t\t\tif (buffer != null && buffer.Length < 32) throw new ArgumentOutOfRangeException(\"buffer\", \"Buffer should be at least 32 bytes long.\");\n\n\t\t\tthis.context = context;\n\t\t\tthis.outputStream = stream;\n\t\t\tthis.buffer = buffer ?? new byte[DEFAULT_BUFFER_SIZE];\n\t\t\tthis.bitConverter = EndianBitConverter.Big;\n\t\t\tthis.bytesWritten = 0;\n\t\t}\n\n\t\tpublic SerializationContext Context\n\t\t{\n\t\t\tget { return this.context; }\n\t\t}\n\n\t\tpublic long CharactersWritten\n\t\t{\n\t\t\tget { return this.bytesWritten; }\n\t\t}\n\n\t\tpublic void Flush()\n\t\t{\n\t\t\tthis.outputStream.Flush();\n\t\t}\n\n\t\tpublic void Write(string value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tthis.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar bytes = this.context.Encoding.GetBytes(value);\n\t\t\tif (bytes.Length < 32)\n\t\t\t{\n\t\t\t\tvar formatByte = (byte)(bytes.Length | (byte)MsgPackType.FixStrStart);\n\t\t\t\tthis.buffer[0] = formatByte;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (bytes.Length <= byte.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Str8);\n\t\t\t\tthis.buffer[0] = (byte)bytes.Length;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (bytes.Length <= ushort.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Str16);\n\t\t\t\tthis.bitConverter.CopyBytes((ushort)bytes.Length, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Str32);\n\t\t\t\tthis.bitConverter.CopyBytes((uint)bytes.Length, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\t\tthis.bytesWritten += 4;\n\t\t\t}\n\n\t\t\tthis.outputStream.Write(bytes, 0, bytes.Length);\n\t\t\tthis.bytesWritten += bytes.Length;\n\t\t}\n\n\t\tpublic void Write(JsonMember value)\n\t\t{\n\t\t\tvar name = value.NameString;\n\t\t\tif (value.IsEscapedAndQuoted)\n\t\t\t\tname = JsonUtils.UnescapeAndUnquote(name);\n\n\t\t\tthis.WriteString(name);\n\t\t}\n\n\t\tpublic void Write(int number)\n\t\t{\n\t\t\tif (number >= -32 && number < 0)\n\t\t\t{\n\t\t\t\tvar formatByte = unchecked((byte)number);\n\t\t\t\tthis.buffer[0] = formatByte;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (number >= 0 && number < 128)\n\t\t\t{\n\t\t\t\tvar formatByte = unchecked((byte)number);\n\t\t\t\tthis.buffer[0] = formatByte;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (number <= sbyte.MaxValue && number >= sbyte.MinValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Int8);\n\t\t\t\tthis.buffer[0] = unchecked((byte)(sbyte)number);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (number <= short.MaxValue && number >= short.MinValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Int16);\n\t\t\t\tthis.bitConverter.CopyBytes(checked((short)number), this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Int32);\n\t\t\t\tthis.bitConverter.CopyBytes((int)number, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\t\tthis.bytesWritten += 4;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(uint number)\n\t\t{\n\t\t\tif (number < 128)\n\t\t\t{\n\t\t\t\tvar formatByte = checked((byte)number);\n\t\t\t\tthis.buffer[0] = formatByte;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (number <= byte.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.UInt8);\n\t\t\t\tthis.buffer[0] = checked((byte)number);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (number <= ushort.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.UInt16);\n\t\t\t\tthis.bitConverter.CopyBytes(checked((ushort)number), this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.UInt32);\n\t\t\t\tthis.bitConverter.CopyBytes((uint)number, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\t\tthis.bytesWritten += 4;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(long number)\n\t\t{\n\t\t\tif (number <= int.MaxValue && number >= int.MinValue)\n\t\t\t{\n\t\t\t\tthis.Write(checked((int)number));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.WriteType(MsgPackType.Int64);\n\t\t\tthis.bitConverter.CopyBytes(number, this.buffer, 0);\n\t\t\tthis.outputStream.Write(this.buffer, 0, 8);\n\t\t\tthis.bytesWritten += 8;\n\t\t}\n\n\t\tpublic void Write(ulong number)\n\t\t{\n\t\t\tif (number <= uint.MaxValue)\n\t\t\t{\n\t\t\t\tthis.Write(checked((uint)number));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.WriteType(MsgPackType.UInt64);\n\t\t\tthis.bitConverter.CopyBytes(number, this.buffer, 0);\n\t\t\tthis.outputStream.Write(this.buffer, 0, 8);\n\t\t\tthis.bytesWritten += 8;\n\t\t}\n\n\t\tpublic void Write(float number)\n\t\t{\n\t\t\tthis.WriteType(MsgPackType.Float32);\n\t\t\tthis.bitConverter.CopyBytes(number, this.buffer, 0);\n\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\tthis.bytesWritten += 4;\n\t\t}\n\n\t\tpublic void Write(double number)\n\t\t{\n\t\t\tthis.WriteType(MsgPackType.Float64);\n\t\t\tthis.bitConverter.CopyBytes(number, this.buffer, 0);\n\t\t\tthis.outputStream.Write(this.buffer, 0, 8);\n\t\t\tthis.bytesWritten += 8;\n\t\t}\n\n\t\tpublic void Write(decimal number)\n\t\t{\n\t\t\tvar extensionData = this.GetWriteBuffer();\n\t\t\tvar extensionType = default(sbyte);\n\t\t\tif (this.context.ExtensionTypeHandler.TryWrite(number, out extensionType, ref extensionData))\n\t\t\t{\n\t\t\t\tthis.Write(extensionType, extensionData);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar decimalStr = number.ToString(null, this.context.Format);\n\t\t\t\tthis.Write(decimalStr);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(bool value)\n\t\t{\n\t\t\tif (value)\n\t\t\t\tthis.WriteType(MsgPackType.True);\n\t\t\telse\n\t\t\t\tthis.WriteType(MsgPackType.False);\n\t\t}\n\n\t\tpublic void Write(DateTime dateTime)\n\t\t{\n\t\t\tvar extensionData = this.GetWriteBuffer();\n\t\t\tvar extensionType = default(sbyte);\n\t\t\tif (this.context.ExtensionTypeHandler.TryWrite(dateTime, out extensionType, ref extensionData))\n\t\t\t{\n\t\t\t\tthis.Write(extensionType, extensionData);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (dateTime.Kind == DateTimeKind.Unspecified)\n\t\t\t\t\tdateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc);\n\n\t\t\t\tvar dateTimeFormat = this.Context.DateTimeFormats.FirstOrDefault() ?? \"o\";\n\t\t\t\tif (dateTimeFormat.IndexOf('z') >= 0 && dateTime.Kind != DateTimeKind.Local)\n\t\t\t\t\tdateTime = dateTime.ToLocalTime();\n\n\t\t\t\tvar dateString = dateTime.ToString(dateTimeFormat, this.Context.Format);\n\n\t\t\t\tthis.Write(dateString);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(DateTimeOffset dateTimeOffset)\n\t\t{\n\t\t\tvar extensionData = this.GetWriteBuffer();\n\t\t\tvar extensionType = default(sbyte);\n\t\t\tif (this.context.ExtensionTypeHandler.TryWrite(dateTimeOffset, out extensionType, ref extensionData))\n\t\t\t{\n\t\t\t\tthis.Write(extensionType, extensionData);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar dateTimeFormat = this.Context.DateTimeFormats.FirstOrDefault() ?? \"o\";\n\t\t\t\tvar dateString = dateTimeOffset.ToString(dateTimeFormat, this.Context.Format);\n\t\t\t\tthis.Write(dateString);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(byte[] value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tthis.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (value.Length < byte.MaxValue)\n\t\t\t{\n\t\t\t\tthis.buffer[0] = (byte)MsgPackType.Bin8;\n\t\t\t\tthis.buffer[1] = (byte)value.Length;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse if (value.Length < ushort.MaxValue)\n\t\t\t{\n\t\t\t\tthis.buffer[0] = (byte)MsgPackType.Bin16;\n\t\t\t\tthis.bitConverter.CopyBytes(checked((ushort)value.Length), this.buffer, 1);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 3);\n\t\t\t\tthis.bytesWritten += 3;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.buffer[0] = (byte)MsgPackType.Bin32;\n\t\t\t\tthis.bitConverter.CopyBytes(checked((uint)value.Length), this.buffer, 1);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 5);\n\t\t\t\tthis.bytesWritten += 5;\n\t\t\t}\n\t\t\tthis.outputStream.Write(value, 0, value.Length);\n\t\t\tthis.bytesWritten += value.Length;\n\t\t}\n\n\t\tpublic void Write(sbyte type, ArraySegment<byte> data)\n\t\t{\n\t\t\tif (data.Array == null)\n\t\t\t{\n\t\t\t\tthis.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (data.Count == 1)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.FixExt1);\n\t\t\t}\n\t\t\telse if (data.Count == 2)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.FixExt2);\n\t\t\t}\n\t\t\telse if (data.Count == 4)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.FixExt4);\n\t\t\t}\n\t\t\telse if (data.Count == 8)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.FixExt8);\n\t\t\t}\n\t\t\telse if (data.Count == 16)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.FixExt16);\n\t\t\t}\n\t\t\telse if (data.Count <= byte.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Ext8);\n\t\t\t\tthis.buffer[0] = (byte)data.Count;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (data.Count <= ushort.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Ext16);\n\t\t\t\tthis.bitConverter.CopyBytes((ushort)data.Count, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Ext32);\n\t\t\t\tthis.bitConverter.CopyBytes((uint)data.Count, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\t\tthis.bytesWritten += 4;\n\t\t\t}\n\n\t\t\t// write extension type\n\t\t\tthis.buffer[0] = unchecked((byte)type);\n\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\tthis.bytesWritten += 1;\n\n\t\t\tthis.outputStream.Write(data.Array, data.Offset, data.Count);\n\t\t\tthis.bytesWritten += data.Count;\n\t\t}\n\n\t\tpublic void WriteObjectBegin(int numberOfMembers)\n\t\t{\n\t\t\tif (numberOfMembers < 0) throw new ArgumentOutOfRangeException(\"numberOfMembers\");\n\n\t\t\tif (numberOfMembers < 16)\n\t\t\t{\n\t\t\t\tvar formatByte = (byte)(numberOfMembers | (byte)MsgPackType.FixMapStart);\n\t\t\t\tthis.buffer[0] = formatByte;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten += 1;\n\t\t\t}\n\t\t\telse if (numberOfMembers <= ushort.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Map16);\n\t\t\t\tthis.bitConverter.CopyBytes((ushort)numberOfMembers, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Map32);\n\t\t\t\tthis.bitConverter.CopyBytes((int)numberOfMembers, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\t\tthis.bytesWritten += 4;\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteObjectEnd()\n\t\t{\n\t\t}\n\n\t\tpublic void WriteArrayBegin(int numberOfMembers)\n\t\t{\n\t\t\tif (numberOfMembers < 0) throw new ArgumentOutOfRangeException(\"numberOfMembers\");\n\n\t\t\tif (numberOfMembers < 16)\n\t\t\t{\n\t\t\t\tvar formatByte = (byte)(numberOfMembers | (byte)MsgPackType.FixArrayStart);\n\t\t\t\tthis.buffer[0] = formatByte;\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\t\tthis.bytesWritten++;\n\t\t\t}\n\t\t\telse if (numberOfMembers <= ushort.MaxValue)\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Array16);\n\t\t\t\tthis.bitConverter.CopyBytes((ushort)numberOfMembers, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 2);\n\t\t\t\tthis.bytesWritten += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.WriteType(MsgPackType.Array32);\n\t\t\t\tthis.bitConverter.CopyBytes((int)numberOfMembers, this.buffer, 0);\n\t\t\t\tthis.outputStream.Write(this.buffer, 0, 4);\n\t\t\t\tthis.bytesWritten += 4;\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteArrayEnd()\n\t\t{\n\t\t}\n\n\t\tpublic void WriteNull()\n\t\t{\n\t\t\tthis.WriteType(MsgPackType.Nil);\n\t\t}\n\n\t\tprivate void WriteType(MsgPackType token)\n\t\t{\n\t\t\tthis.buffer[0] = (byte)token;\n\t\t\tthis.outputStream.Write(this.buffer, 0, 1);\n\t\t\tthis.bytesWritten++;\n\t\t}\n\n\t\tpublic void WriteJson(string jsonString)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic void WriteJson(char[] jsonString, int index, int charCount)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic void Reset()\n\t\t{\n\t\t\tthis.bytesWritten = 0;\n\t\t\tArray.Clear(this.buffer, 0, this.buffer.Length);\n\t\t}\n\n\t\tinternal ArraySegment<byte> GetWriteBuffer()\n\t\t{\n\t\t\treturn new ArraySegment<byte>(this.buffer, 16, this.buffer.Length - 16);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/MsgPackWriter.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 4baefb230851459abd8b2a393debe8fb\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/UnknownMsgPackExtentionTypeException.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Runtime.Serialization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t[Serializable]\n\tpublic sealed class UnknownMsgPackExtentionTypeException : SerializationException\n\t{\n\t\tpublic UnknownMsgPackExtentionTypeException(string message, Exception innerException) : base(message, innerException)\n\t\t{\n\t\t}\n\n\t\tpublic UnknownMsgPackExtentionTypeException(string message) : base(message)\n\t\t{\n\t\t}\n\n\t\tpublic UnknownMsgPackExtentionTypeException(sbyte invalidExtType)\n\t\t\t: base(string.Format(\"Unknown MessagePack extention type '{0}' was readed from stream.\", invalidExtType))\n\t\t{\n\t\t}\n\n\t\tprivate UnknownMsgPackExtentionTypeException(SerializationInfo info, StreamingContext context)\n\t\t\t: base(info, context)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/UnknownMsgPackExtentionTypeException.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: d57ba530cdc14db5b5cac872c64cdbde\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/UnknownMsgPackFormatException.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Runtime.Serialization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.MessagePack\n{\n\t[Serializable]\n\tpublic sealed class UnknownMsgPackFormatException : SerializationException\n\t{\n\t\tpublic UnknownMsgPackFormatException(string message, Exception innerException) : base(message, innerException)\n\t\t{\n\t\t}\n\n\t\tpublic UnknownMsgPackFormatException(string message) : base(message)\n\t\t{\n\t\t}\n\n\t\tpublic UnknownMsgPackFormatException(byte invalidValue)\n\t\t\t: base(string.Format(\"Unknown MessagePack format '{0}' was readed from stream.\", invalidValue))\n\t\t{\n\t\t}\n\n#if !NETSTANDARD\n\t\tprivate UnknownMsgPackFormatException(SerializationInfo info, StreamingContext context)\n\t\t\t: base(info, context)\n\t\t{\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack/UnknownMsgPackFormatException.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 2b91b6c0c5164e7482bd7806d504540b\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MessagePack.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 6e931c62d9d54c0086adef8ca78c048b\nfolderAsset: yes\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/DataMemberDescription.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Reflection;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Metadata\n{\n\tinternal abstract class DataMemberDescription : MemberDescription\n\t{\n\t\tpublic abstract bool CanGet { get; }\n\t\tpublic abstract bool CanSet { get; }\n\t\tpublic object DefaultValue { get; private set; }\n\t\tpublic abstract Type ValueType { get; }\n\n\t\tprotected DataMemberDescription(TypeDescription typeDescription, MemberInfo member)\n\t\t\t: base(typeDescription, member)\n\t\t{\n\t\t\tvar defaultValue =\n\t\t\t\t(DefaultValueAttribute) this.GetAttributesOrEmptyList(typeof (DefaultValueAttribute)).FirstOrDefault();\n\t\t\tif (defaultValue != null)\n\t\t\t\tthis.DefaultValue = defaultValue.Value;\n\t\t}\n\n\t\tpublic abstract object GetValue(object target);\n\t\tpublic abstract void SetValue(object target, object value);\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/DataMemberDescription.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 1bc4a7488c8d43b785c5a2e7cf2ab6a5\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/FieldDescription.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Reflection;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Metadata\n{\n\tinternal sealed class FieldDescription : DataMemberDescription\n\t{\n\t\tprivate readonly FieldInfo fieldInfo;\n\t\tprivate readonly Func<object, object> getFn;\n\t\tprivate readonly Action<object, object> setFn;\n\n\t\tpublic override bool CanGet { get { return true; } }\n\t\tpublic override bool CanSet { get { return this.fieldInfo.IsInitOnly == false; } }\n\t\tpublic override Type ValueType { get { return this.fieldInfo.FieldType; } }\n\n\t\tpublic FieldDescription(TypeDescription typeDescription, FieldInfo fieldInfo)\n\t\t\t: base(typeDescription, fieldInfo)\n\t\t{\n\t\t\tif (fieldInfo == null) throw new ArgumentNullException(\"fieldInfo\");\n\n\t\t\tthis.fieldInfo = fieldInfo;\n\n\t\t\tMetadataReflection.TryGetMemberAccessFunc(fieldInfo, out this.getFn, out this.setFn);\n\n\t\t}\n\n\t\tpublic override object GetValue(object target)\n\t\t{\n\t\t\tif (!this.CanGet) throw new InvalidOperationException(\"Field is write-only.\");\n\n\t\t\tif (this.getFn != null)\n\t\t\t\treturn this.getFn(target);\n\t\t\telse\n\t\t\t\treturn fieldInfo.GetValue(target);\n\t\t}\n\n\t\tpublic override void SetValue(object target, object value)\n\t\t{\n\t\t\tif (!this.CanSet) throw new InvalidOperationException(\"Field is read-only.\");\n\n\t\t\tif (this.setFn != null)\n\t\t\t\tthis.setFn(target, value);\n\t\t\telse\n\t\t\t\tthis.fieldInfo.SetValue(target, value);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/FieldDescription.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 9cf871662e6c414a8cae05fdc578c14b\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/MemberDescription.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\nusing System.Reflection;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Metadata\n{\n\tinternal abstract class MemberDescription\n\t{\n\t\tprotected const string DATA_CONTRACT_ATTRIBUTE_NAME = \"DataContractAttribute\";\n\t\tprotected const string DATA_MEMBER_ATTRIBUTE_NAME = \"DataMemberAttribute\";\n\t\tprotected const string IGNORE_DATA_MEMBER_ATTRIBUTE_NAME = \"IgnoreDataMemberAttribute\";\n\n\t\tprivate readonly string name;\n\t\tprivate readonly MemberInfo member;\n\t\tprivate readonly ReadOnlyCollection<Attribute> attributes;\n\t\tprivate readonly ILookup<Type, Attribute> attributesByType;\n\n\t\tpublic MemberInfo Member { get { return this.member; } }\n\t\tpublic ReadOnlyCollection<Attribute> Attributes { get { return this.attributes; } }\n\t\tpublic string Name { get { return this.name; } }\n\n\t\tprotected MemberDescription(TypeDescription typeDescription, MemberInfo member)\n\t\t{\n\t\t\tif (member == null) throw new ArgumentNullException(\"member\");\n\n\t\t\tthis.member = member;\n\t\t\tthis.name = member.Name;\n\n\t\t\tvar attributesList = new List<Attribute>();\n\t\t\tforeach (Attribute attr in member.GetCustomAttributes(true))\n\t\t\t\tattributesList.Add(attr);\n\n\t\t\tif (typeDescription != null && typeDescription.IsDataContract)\n\t\t\t{\n\t\t\t\tvar dataMemberAttribute = attributesList.FirstOrDefault(a => a.GetType().Name == DATA_MEMBER_ATTRIBUTE_NAME);\n\t\t\t\tif (dataMemberAttribute != null)\n\t\t\t\t\tthis.name = ReflectionExtensions.GetDataMemberName(dataMemberAttribute) ?? this.name;\n\t\t\t}\n\n\t\t\tthis.attributes = new ReadOnlyCollection<Attribute>(attributesList);\n\t\t\tthis.attributesByType = attributesList.ToLookup(a => a.GetType());\n\t\t}\n\n\t\tpublic bool HasAttributes(Type type)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\n\t\t\treturn this.attributesByType.Contains(type);\n\t\t}\n\n\t\tpublic IEnumerable<Attribute> GetAttributesOrEmptyList(Type type)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\n\t\t\treturn this.attributesByType[type];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/MemberDescription.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 33506f0ce7e04e338380f997bb5fd861\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/MetadataReflection.cs",
    "content": "#if UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4 || UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER\n#define UNITY\n#endif\n/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Reflection;\nusing System.Reflection.Emit;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Metadata\n{\n\tinternal static class MetadataReflection\n\t{\n\t\t/// <summary>\n\t\t/// Set to true to disable access optimizations (generated read/write access delegates) in AOT runtime.\n\t\t/// </summary>\n\t\tpublic static bool AotRuntime;\n\n\t\tprivate static readonly Dictionary<MemberInfo, Func<object, object>> ReadFunctions;\n\t\tprivate static readonly Dictionary<MemberInfo, Action<object, object>> WriteFunctions;\n\t\tprivate static readonly Dictionary<MemberInfo, Func<object>> ConstructorFunctions;\n\n\t\tstatic MetadataReflection()\n\t\t{\n#if ((UNITY_WEBGL || UNITY_IOS || ENABLE_IL2CPP) && !UNITY_EDITOR)\n\t\t\tAotRuntime = true;\n#else\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// try compile expression\n\t\t\t\tExpression.Lambda<Func<bool>>(Expression.Constant(true)).Compile();\n#if (NET35 || UNITY) && !NET_STANDARD_2_0\n\t\t\t\tvar voidDynamicMethod = new DynamicMethod(\"TestVoidMethod\", typeof(void), Type.EmptyTypes, restrictedSkipVisibility: true);\n\t\t\t\tvar il = voidDynamicMethod.GetILGenerator();\n\t\t\t\til.Emit(OpCodes.Nop);\n\t\t\t\tvoidDynamicMethod.CreateDelegate(typeof(Action));\n#endif\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tAotRuntime = true;\n\t\t\t}\n#endif\n\t\t\tReadFunctions = new Dictionary<MemberInfo, Func<object, object>>();\n\t\t\tWriteFunctions = new Dictionary<MemberInfo, Action<object, object>>();\n\t\t\tConstructorFunctions = new Dictionary<MemberInfo, Func<object>>();\n\t\t}\n\n\t\tpublic static bool TryGetMemberAccessFunc(MethodInfo getMethod, MethodInfo setMethod, out Func<object, object> getFn, out Action<object, object> setFn)\n\t\t{\n\t\t\tgetFn = null;\n\t\t\tsetFn = null;\n\n\n\t\t\tif (AotRuntime)\n\t\t\t\treturn false;\n\n\t\t\tif (getMethod != null && !getMethod.IsStatic && getMethod.GetParameters().Length == 0)\n\t\t\t{\n\t\t\t\tlock (ReadFunctions)\n\t\t\t\t{\n\t\t\t\t\tif (ReadFunctions.TryGetValue(getMethod, out getFn) == false)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar instanceParam = Expression.Parameter(typeof(object), \"instance\");\n\t\t\t\t\t\tvar declaringType = getMethod.DeclaringType;\n\t\t\t\t\t\tDebug.Assert(declaringType != null, \"getMethod.DeclaringType != null\");\n\t\t\t\t\t\tgetFn = Expression.Lambda<Func<object, object>>(\n\t\t\t\t\t\t\tExpression.Convert(\n\t\t\t\t\t\t\t\tExpression.Call(\n\t\t\t\t\t\t\t\t\tExpression.Convert(instanceParam, declaringType), getMethod),\n\t\t\t\t\t\t\t\t\ttypeof(object)),\n\t\t\t\t\t\t\t\tinstanceParam\n\t\t\t\t\t\t).Compile();\n\t\t\t\t\t\tReadFunctions.Add(getMethod, getFn);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (setMethod != null && !setMethod.IsStatic && setMethod.GetParameters().Length == 1 && setMethod.DeclaringType != null && setMethod.DeclaringType.IsValueType == false)\n\t\t\t{\n\t\t\t\tlock (WriteFunctions)\n\t\t\t\t{\n\t\t\t\t\tif (WriteFunctions.TryGetValue(setMethod, out setFn) == false)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar instanceParam = Expression.Parameter(typeof(object), \"instance\");\n\t\t\t\t\t\tvar valueParam = Expression.Parameter(typeof(object), \"value\");\n\t\t\t\t\t\tvar declaringType = setMethod.DeclaringType;\n\t\t\t\t\t\tvar valueType = setMethod.GetParameters()[0].ParameterType;\n\t\t\t\t\t\tDebug.Assert(declaringType != null, \"setMethod.DeclaringType != null\");\n\n\t\t\t\t\t\tsetFn = ((Expression<Action<object, object>>)Expression.Lambda(typeof(Action<object, object>),\n\t\t\t\t\t\t\tExpression.Call(\n\t\t\t\t\t\t\t\tExpression.Convert(instanceParam, declaringType),\n\t\t\t\t\t\t\t\tsetMethod,\n\t\t\t\t\t\t\t\tExpression.Convert(valueParam, valueType)),\n\t\t\t\t\t\t\tinstanceParam,\n\t\t\t\t\t\t\tvalueParam\n\t\t\t\t\t\t)).Compile();\n\t\t\t\t\t\tWriteFunctions.Add(setMethod, setFn);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tpublic static bool TryGetMemberAccessFunc(FieldInfo fieldInfo, out Func<object, object> getFn, out Action<object, object> setFn)\n\t\t{\n\t\t\tgetFn = null;\n\t\t\tsetFn = null;\n\n\t\t\tif (AotRuntime || fieldInfo.IsStatic)\n\t\t\t\treturn false;\n\n\t\t\tlock (ReadFunctions)\n\t\t\t{\n\t\t\t\tif (ReadFunctions.TryGetValue(fieldInfo, out getFn) == false)\n\t\t\t\t{\n\t\t\t\t\tvar instanceParam = Expression.Parameter(typeof(object), \"instance\");\n\t\t\t\t\tvar declaringType = fieldInfo.DeclaringType;\n\t\t\t\t\tDebug.Assert(declaringType != null, \"getMethodDeclaringType != null\");\n\t\t\t\t\tgetFn = Expression.Lambda<Func<object, object>>(\n\t\t\t\t\t\tExpression.Convert(\n\t\t\t\t\t\t\tExpression.Field(\n\t\t\t\t\t\t\t\tExpression.Convert(instanceParam, declaringType),\n\t\t\t\t\t\t\t\tfieldInfo),\n\t\t\t\t\t\t\t\ttypeof(object)),\n\t\t\t\t\t\t\tinstanceParam\n\t\t\t\t\t).Compile();\n\t\t\t\t\tReadFunctions.Add(fieldInfo, getFn);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (fieldInfo.IsInitOnly == false && fieldInfo.DeclaringType != null && fieldInfo.DeclaringType.IsValueType == false)\n\t\t\t{\n\t\t\t\tlock (WriteFunctions)\n\t\t\t\t{\n\t\t\t\t\tif (WriteFunctions.TryGetValue(fieldInfo, out setFn) == false)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar declaringType = fieldInfo.DeclaringType;\n\t\t\t\t\t\tDebug.Assert(declaringType != null, \"fieldInfo.DeclaringType != null\");\n\t\t\t\t\t\tvar fieldType = fieldInfo.FieldType;\n#if (NET35 || UNITY) && !NET_STANDARD_2_0\n\t\t\t\t\t\tvar setDynamicMethod = new DynamicMethod(declaringType.FullName + \"::\" + fieldInfo.Name, typeof(void), new Type[] { typeof(object), typeof(object) }, restrictedSkipVisibility: true);\n\t\t\t\t\t\tvar il = setDynamicMethod.GetILGenerator();\n\n\t\t\t\t\t\til.Emit(OpCodes.Ldarg_0); // instance\n\t\t\t\t\t\til.Emit(OpCodes.Castclass, declaringType);\n\t\t\t\t\t\til.Emit(OpCodes.Ldarg_1); // value\n\t\t\t\t\t\tif (fieldType.IsValueType)\n\t\t\t\t\t\t\til.Emit(OpCodes.Unbox_Any, fieldType);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\til.Emit(OpCodes.Castclass, fieldType);\n\t\t\t\t\t\til.Emit(OpCodes.Stfld, fieldInfo); // call instance.Set(value)\n\t\t\t\t\t\til.Emit(OpCodes.Ret);\n\n\t\t\t\t\t\tsetFn = (Action<object, object>)setDynamicMethod.CreateDelegate(typeof(Action<object, object>));\n#else\n\t\t\t\t\t\tvar instanceParam = Expression.Parameter(typeof(object), \"instance\");\n\t\t\t\t\t\tvar valueParam = Expression.Parameter(typeof(object), \"value\");\n\n\t\t\t\t\t\tsetFn = ((Expression<Action<object, object>>)Expression.Lambda(typeof(Action<object, object>),\n\t\t\t\t\t\t\tExpression.Assign(\n\t\t\t\t\t\t\t\tExpression.Field(Expression.Convert(instanceParam, declaringType), fieldInfo), \n\t\t\t\t\t\t\t\tExpression.Convert(valueParam, fieldType)),\n\t\t\t\t\t\t\tinstanceParam,\n\t\t\t\t\t\t\tvalueParam\n\t\t\t\t\t\t)).Compile();\n#endif\n\t\t\t\t\t\tWriteFunctions.Add(fieldInfo, setFn);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t\tpublic static bool TryGetConstructor(Type type, out Func<object> ctrFn, out ConstructorInfo defaultConstructor)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\n\t\t\tctrFn = null;\n\t\t\tdefaultConstructor = null;\n\n\t\t\tif (type.IsAbstract || type.IsInterface)\n\t\t\t\treturn false;\n\n\t\t\tdefaultConstructor = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(ctr => ctr.GetParameters().Length == 0);\n\n\t\t\tif (AotRuntime && defaultConstructor != null) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (defaultConstructor == null)\n\t\t\t\treturn false;\n\n\t\t\tlock (ConstructorFunctions)\n\t\t\t{\n\t\t\t\tif (ConstructorFunctions.TryGetValue(type, out ctrFn))\n\t\t\t\t\treturn true;\n\n\t\t\t\tctrFn = Expression.Lambda<Func<object>>(\n\t\t\t\t\tExpression.Convert(\n\t\t\t\t\t\tExpression.New(defaultConstructor),\n\t\t\t\t\t\ttypeof(object))\n\t\t\t\t\t).Compile();\n\n\t\t\t\tConstructorFunctions.Add(type, ctrFn);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/MetadataReflection.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: a818bb9057d9405a939b62a05497176a\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/PropertyDescription.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Reflection;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Metadata\n{\n\tinternal sealed class PropertyDescription : DataMemberDescription\n\t{\n\t\tprivate readonly PropertyInfo propertyInfo;\n\t\tprivate readonly Func<object, object> getFn;\n\t\tprivate readonly Action<object, object> setFn;\n\t\tprivate readonly MethodInfo getMethod;\n\t\tprivate readonly MethodInfo setMethod;\n\n\t\tpublic override bool CanGet { get { return this.getMethod != null; } }\n\t\tpublic override bool CanSet { get { return this.setMethod != null; } }\n\t\tpublic override Type ValueType { get { return this.propertyInfo.PropertyType; } }\n\n\t\tpublic PropertyDescription(TypeDescription typeDescription, PropertyInfo propertyInfo)\n\t\t\t: base(typeDescription, propertyInfo)\n\t\t{\n\t\t\tif (propertyInfo == null) throw new ArgumentNullException(\"propertyInfo\");\n\n\t\t\tthis.propertyInfo = propertyInfo;\n\n\t\t\tthis.getMethod = propertyInfo.GetGetMethod(nonPublic: true);\n\t\t\tthis.setMethod = propertyInfo.GetSetMethod(nonPublic: true);\n\n\t\t\tMetadataReflection.TryGetMemberAccessFunc(this.getMethod, this.setMethod, out this.getFn, out this.setFn);\n\t\t}\n\n\t\tpublic override object GetValue(object target)\n\t\t{\n\t\t\tif (!this.CanGet) throw new InvalidOperationException(\"Property is write-only.\");\n\n\t\t\tif (this.getFn != null)\n\t\t\t\treturn this.getFn(target);\n\t\t\telse\n\t\t\t\treturn this.getMethod.Invoke(target, null);\n\t\t}\n\t\tpublic override void SetValue(object target, object value)\n\t\t{\n\t\t\tif (!this.CanSet) throw new InvalidOperationException(\"Property is read-only.\");\n\n\t\t\tif (this.setFn != null)\n\t\t\t\tthis.setFn(target, value);\n\t\t\telse\n\t\t\t\tthis.setMethod.Invoke(target, new object[] { value });\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/PropertyDescription.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 6abfcb3759b145eaa0fe028ff0f8f3f2\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/TypeDescription.cs",
    "content": "#if UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4 || UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER\n#define UNITY\n#endif\n/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\n#if NET35 || UNITY\nusing TypeInfo = System.Type;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Metadata\n{\n\tinternal class TypeDescription : MemberDescription\n\t{\n\t\tprivate static readonly Dictionary<TypeInfo, TypeDescription> TypeDescriptions = new Dictionary<TypeInfo, TypeDescription>();\n\t\tprivate static readonly object[] EmptyParameters = new object[0];\n\n\t\tprivate readonly TypeInfo objectType;\n\t\tprivate readonly Func<object> constructorFn;\n\t\tprivate readonly ConstructorInfo defaultConstructor;\n\t\tprivate readonly ReadOnlyCollection<DataMemberDescription> members;\n\t\tprivate readonly Dictionary<string, DataMemberDescription> membersByName;\n\n\t\tpublic TypeInfo ObjectType { get { return this.objectType; } }\n\t\tpublic bool IsAnonymousType { get; private set; }\n\t\tpublic bool IsEnumerable { get; private set; }\n\t\tpublic bool IsDictionary { get; private set; }\n\t\tpublic bool IsDataContract { get; private set; }\n\t\tpublic bool IsSerializable { get; private set; }\n\t\tpublic ReadOnlyCollection<DataMemberDescription> Members { get { return this.members; } }\n\n\t\tpublic TypeDescription(TypeInfo objectType)\n\t\t\t: base(null, objectType)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\n\t\t\tthis.objectType = objectType;\n\t\t\tthis.IsDataContract = this.Attributes.Any(attribute => attribute.GetType().Name == DATA_CONTRACT_ATTRIBUTE_NAME);\n#if NETSTANDARD\n\t\t\tthis.IsSerializable = this.objectType.GetCustomAttributes(typeof(SerializableAttribute), true).Any();\n#else\n\t\t\tthis.IsSerializable = objectType.IsSerializable;\n#endif\n\t\t\tthis.IsEnumerable = this.objectType.IsInstantiationOf(typeof(Enumerable)) && this.objectType != typeof(string);\n\t\t\tthis.IsDictionary = typeof(IDictionary).GetTypeInfo().IsAssignableFrom(this.objectType);\n\t\t\tthis.IsAnonymousType = this.objectType.IsSealed && this.objectType.IsNotPublic && this.objectType.GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Any();\n\n\t\t\tvar allMembers = this.FindMembers(this.objectType);\n\n\t\t\tthis.members = allMembers.AsReadOnly();\n\t\t\tthis.membersByName = allMembers.ToDictionary(m => m.Name, StringComparer.Ordinal);\n\n\t\t\tMetadataReflection.TryGetConstructor(this.objectType, out this.constructorFn, out this.defaultConstructor);\n\t\t}\n\n\t\tprivate List<DataMemberDescription> FindMembers(TypeInfo objectType)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\n\t\t\tvar members = new List<DataMemberDescription>();\n\t\t\tvar memberNames = new HashSet<string>(StringComparer.Ordinal);\n\t\t\tvar isOptIn = objectType.GetCustomAttributes(false).Any(a => a.GetType().Name == DATA_CONTRACT_ATTRIBUTE_NAME);\n\t\t\tvar searchFlags = BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | (isOptIn ? BindingFlags.NonPublic : 0);\n\t\t\tvar properties = objectType.GetProperties(searchFlags);\n\t\t\tvar fields = objectType.GetFields(searchFlags);\n\n\t\t\tforeach (var member in properties.Cast<MemberInfo>().Concat(fields.Cast<MemberInfo>()))\n\t\t\t{\n\t\t\t\tif (member is PropertyInfo && (member as PropertyInfo).GetIndexParameters().Length != 0)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar dataMemberAttribute = member.GetCustomAttributes(false).FirstOrDefault(a => a.GetType().Name == DATA_MEMBER_ATTRIBUTE_NAME);\n\t\t\t\tvar ignoreMemberAttribute = member.GetCustomAttributes(false).FirstOrDefault(a => a.GetType().Name == IGNORE_DATA_MEMBER_ATTRIBUTE_NAME);\n\n\t\t\t\tif (isOptIn && dataMemberAttribute == null)\n\t\t\t\t\tcontinue;\n\t\t\t\telse if (!isOptIn && ignoreMemberAttribute != null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar dataMember = default(DataMemberDescription);\n\t\t\t\tif (member is PropertyInfo) dataMember = new PropertyDescription(this, member as PropertyInfo);\n\t\t\t\telse if (member is FieldInfo) dataMember = new FieldDescription(this, member as FieldInfo);\n\t\t\t\telse throw new InvalidOperationException(\"Unknown member type. Should be PropertyInfo or FieldInfo.\");\n\n\t\t\t\tif (string.IsNullOrEmpty(dataMember.Name))\n\t\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(objectType, \"has no members with empty name\");\n\n\t\t\t\tif (memberNames.Contains(dataMember.Name))\n\t\t\t\t{\n\t\t\t\t\tvar conflictingMember = members.First(m => m.Name == dataMember.Name);\n\t\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(objectType, string.Format(\"has no duplicate member's name '{0}' ('{1}.{2}' and '{3}.{4}')\", dataMember.Name, conflictingMember.Member.DeclaringType.Name, conflictingMember.Member.Name, dataMember.Member.DeclaringType.Name, dataMember.Member.Name));\n\t\t\t\t}\n\n\t\t\t\tmembers.Add(dataMember);\n\t\t\t\tmemberNames.Add(dataMember.Name);\n\t\t\t}\n\n\t\t\treturn members;\n\t\t}\n\n\t\tpublic bool TryGetMember(string name, out DataMemberDescription member)\n\t\t{\n\t\t\treturn this.membersByName.TryGetValue(name, out member);\n\t\t}\n\n\t\tpublic object CreateInstance()\n\t\t{\n\t\t\tif (this.constructorFn != null)\n\t\t\t\treturn this.constructorFn();\n\t\t\telse if (this.defaultConstructor != null && !this.objectType.IsAbstract)\n\t\t\t\treturn this.defaultConstructor.Invoke(EmptyParameters);\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.CantCreateInstanceOfType(this.objectType);\n\t\t}\n\n\t\tpublic static TypeDescription Get(Type type)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\n\t\t\tvar typeInfo = type.GetTypeInfo();\n\t\t\tlock (TypeDescriptions)\n\t\t\t{\n\t\t\t\tTypeDescription objectTypeDescription;\n\t\t\t\tif (!TypeDescriptions.TryGetValue(typeInfo, out objectTypeDescription))\n\t\t\t\t\tTypeDescriptions.Add(typeInfo, objectTypeDescription = new TypeDescription(typeInfo));\n\t\t\t\treturn objectTypeDescription;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn this.objectType.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata/TypeDescription.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 81d49351045b455ba28308583aa6e6c7\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Metadata.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 75ef1581622b423ebeb7f42a7810d1a2\nfolderAsset: yes\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MsgPack.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\nusing GameDevWare.Serialization.MessagePack;\nusing GameDevWare.Serialization.Serializers;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic static class MsgPack\n\t{\n\t\tpublic static string[] DefaultDateTimeFormats { get { return Json.DefaultDateTimeFormats; } set { Json.DefaultDateTimeFormats = value; } }\n\t\tpublic static IFormatProvider DefaultFormat { get { return Json.DefaultFormat; } set { Json.DefaultFormat = value; } }\n\t\tpublic static Encoding DefaultEncoding { get { return Json.DefaultEncoding; } set { Json.DefaultEncoding = value; } }\n\t\tpublic static List<TypeSerializer> DefaultSerializers { get { return Json.DefaultSerializers; } }\n\t\tpublic static MessagePackExtensionTypeHandler ExtensionTypeHandler { get; private set; }\n\n\t\tstatic MsgPack()\n\t\t{\n\t\t\tExtensionTypeHandler = new DefaultMessagePackExtensionTypeHandler(EndianBitConverter.Big);\n\t\t}\n\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream msgPackOutput)\n\t\t{\n\t\t\tSerialize(objectToSerialize, msgPackOutput, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream msgPackOutput, SerializationOptions options)\n\t\t{\n\t\t\tSerialize(objectToSerialize, msgPackOutput, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static void Serialize<T>(T objectToSerialize, Stream msgPackOutput, SerializationContext context)\n\t\t{\n\t\t\tif (msgPackOutput == null) throw new ArgumentNullException(\"msgPackOutput\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\t\t\tvar writer = new MsgPackWriter(msgPackOutput, context);\n\t\t\tif (objectToSerialize == null)\n\t\t\t{\n\t\t\t\twriter.WriteNull();\n\t\t\t\twriter.Flush();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twriter.WriteValue(objectToSerialize, typeof(T));\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, byte[] msgPackInput, int offset, int length)\n\t\t{\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(msgPackInput, offset, length));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, byte[] msgPackInput, int offset, int length, SerializationOptions options)\n\t\t{\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(msgPackInput, offset, length), options);\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, byte[] msgPackInput, int offset, int length, SerializationContext context)\n\t\t{\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\n\t\t\treturn Deserialize(objectType, new MemoryStream(msgPackInput, offset, length), context);\n\t\t}\n\n\t\tpublic static object Deserialize(Type objectType, Stream msgPackInput)\n\t\t{\n\t\t\treturn Deserialize(objectType, msgPackInput, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, Stream msgPackInput, SerializationOptions options)\n\t\t{\n\t\t\treturn Deserialize(objectType, msgPackInput, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static object Deserialize(Type objectType, Stream msgPackInput, SerializationContext context)\n\t\t{\n\t\t\tif (objectType == null) throw new ArgumentNullException(\"objectType\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\t\t\tif (!msgPackInput.CanRead) throw JsonSerializationException.StreamIsNotReadable();\n\n\t\t\tvar reader = new MsgPackReader(msgPackInput, context);\n\t\t\treturn reader.ReadValue(objectType, false);\n\t\t}\n\n\t\tpublic static T Deserialize<T>(byte[] msgPackInput, int offset, int length)\n\t\t{\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(msgPackInput, offset, length));\n\t\t}\n\t\tpublic static T Deserialize<T>(byte[] msgPackInput, int offset, int length, SerializationOptions options)\n\t\t{\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(msgPackInput, offset, length), options);\n\t\t}\n\t\tpublic static T Deserialize<T>(byte[] msgPackInput, int offset, int length, SerializationContext context)\n\t\t{\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\n\t\t\treturn Deserialize<T>(new MemoryStream(msgPackInput, offset, length), context);\n\t\t}\n\n\t\tpublic static T Deserialize<T>(Stream msgPackInput)\n\t\t{\n\t\t\treturn Deserialize<T>(msgPackInput, CreateDefaultContext(SerializationOptions.None));\n\t\t}\n\t\tpublic static T Deserialize<T>(Stream msgPackInput, SerializationOptions options)\n\t\t{\n\t\t\treturn Deserialize<T>(msgPackInput, CreateDefaultContext(options));\n\t\t}\n\t\tpublic static T Deserialize<T>(Stream msgPackInput, SerializationContext context)\n\t\t{\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\t\t\tif (msgPackInput == null) throw new ArgumentNullException(\"msgPackInput\");\n\t\t\tif (!msgPackInput.CanRead) throw JsonSerializationException.StreamIsNotReadable();\n\n\t\t\treturn (T)Deserialize(typeof(T), msgPackInput, context);\n\t\t}\n\n\t\tprivate static SerializationContext CreateDefaultContext(SerializationOptions options)\n\t\t{\n\t\t\treturn new SerializationContext\n\t\t\t{\n\t\t\t\tOptions = options,\n\t\t\t\tEnumSerializerFactory = (enumType) => new EnumNumberSerializer(enumType)\n\t\t\t};\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/MsgPack.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 758e563fe3ff4497a4fb9f284c016ac4\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/PathSegment.cs",
    "content": "using System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic struct PathSegment\n\t{\n\t\tpublic readonly int Index;\n\t\tpublic readonly object MemberName;\n\n\t\tpublic PathSegment(int index)\n\t\t{\n\t\t\tif (index < 0) throw new ArgumentOutOfRangeException(\"index\");\n\n\t\t\tthis.Index = index;\n\t\t\tthis.MemberName = null;\n\t\t}\n\t\tpublic PathSegment(object memberName)\n\t\t{\n\t\t\tif (memberName == null) throw new ArgumentNullException(\"memberName\");\n\n\t\t\tthis.Index = -1;\n\t\t\tthis.MemberName = memberName;\n\t\t}\n\n\t\t/// <inheritdoc />\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (this.Index >= 0)\n\t\t\t{\n\t\t\t\treturn this.Index.ToString();\n\t\t\t}\n\t\t\telse if (this.MemberName != null)\n\t\t\t{\n\t\t\t\treturn this.MemberName.ToString();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn string.Empty;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/PathSegment.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: fcb712e5c13440d993fedb005d30dc78\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/ReflectionExtentions.cs",
    "content": "#if UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_4 || UNITY_4_7 || UNITY_5 || UNITY_5_3_OR_NEWER\n#define UNITY\n#endif\n/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tinternal static class ReflectionExtensions\n\t{\n\t\tprivate static readonly Dictionary<Type, MethodInfo> GetNameMethods = new Dictionary<Type, MethodInfo>();\n\t\tprivate static readonly object[] EmptyArgs = new object[0];\n\n\t\tpublic static bool IsInstantiationOf(this Type type, Type openGenericType)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(\"type\");\n\t\t\tif (openGenericType == null)\n\t\t\t\tthrow new ArgumentNullException(\"openGenericType\");\n\n\t\t\tif (openGenericType.IsGenericType && !openGenericType.IsGenericTypeDefinition)\n\t\t\t\tthrow new ArgumentException(string.Format(\"Type should be open generic type '{0}'.\", openGenericType));\n\n\t\t\tvar genericType = type;\n\t\t\tif (type.IsGenericType)\n\t\t\t{\n\t\t\t\tif (type.IsGenericType && !type.IsGenericTypeDefinition)\n\t\t\t\t\tgenericType = type.GetGenericTypeDefinition();\n\n\t\t\t\tif (genericType == openGenericType || genericType.IsSubclassOf(openGenericType))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// clean\n\t\t\tgenericType = null;\n\n\t\t\t// check interfaces\n\t\t\tforeach (var interfc in type.GetInterfaces())\n\t\t\t{\n\t\t\t\tgenericType = interfc;\n\n\t\t\t\tif (!interfc.IsGenericType)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (!interfc.IsGenericTypeDefinition)\n\t\t\t\t\tgenericType = interfc.GetGenericTypeDefinition();\n\n\t\t\t\tif (genericType == openGenericType || genericType.IsSubclassOf(openGenericType))\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (type.BaseType != null && type.BaseType != typeof (object))\n\t\t\t\treturn IsInstantiationOf(type.BaseType, openGenericType);\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool HasMultipleInstantiations(this Type type, Type openGenericType)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(\"type\");\n\t\t\tif (openGenericType == null)\n\t\t\t\tthrow new ArgumentNullException(\"openGenericType\");\n\n\t\t\tif (openGenericType.IsGenericType && !openGenericType.IsGenericTypeDefinition)\n\t\t\t\tthrow new ArgumentException(string.Format(\"Type should be open generic type '{0}'.\", openGenericType));\n\n\t\t\t// can't has multiple implementations of class\n\t\t\tif (!openGenericType.IsInterface)\n\t\t\t\treturn false;\n\n\t\t\tvar found = 0;\n\n\t\t\tvar genericType = type;\n\t\t\tif (type.IsGenericType)\n\t\t\t{\n\t\t\t\tif (type.IsGenericType && !type.IsGenericTypeDefinition)\n\t\t\t\t\tgenericType = type.GetGenericTypeDefinition();\n\n\t\t\t\tif (genericType == openGenericType || genericType.IsSubclassOf(openGenericType))\n\t\t\t\t\tfound++;\n\t\t\t}\n\t\t\t// clean\n\t\t\tgenericType = null;\n\n\t\t\t// check interfaces\n\t\t\tforeach (var interfc in type.GetInterfaces())\n\t\t\t{\n\t\t\t\tgenericType = interfc;\n\n\t\t\t\tif (!interfc.IsGenericType)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (!interfc.IsGenericTypeDefinition)\n\t\t\t\t\tgenericType = interfc.GetGenericTypeDefinition();\n\n\t\t\t\tif (genericType == openGenericType || genericType.IsSubclassOf(openGenericType))\n\t\t\t\t\tfound++;\n\t\t\t}\n\n\n\t\t\treturn found > 1;\n\t\t}\n\n\t\tpublic static Type[] GetInstantiationArguments(this Type type, Type openGenericType)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(\"type\");\n\t\t\tif (openGenericType == null)\n\t\t\t\tthrow new ArgumentNullException(\"openGenericType\");\n\n\t\t\tif (openGenericType.IsGenericType && !openGenericType.IsGenericTypeDefinition)\n\t\t\t\tthrow new ArgumentException(string.Format(\"Type should be open generic type '{0}'.\", openGenericType));\n\n\t\t\tvar genericType = type;\n\t\t\tif (type.IsGenericType)\n\t\t\t{\n\t\t\t\tif (type.IsGenericType && !type.IsGenericTypeDefinition)\n\t\t\t\t\tgenericType = type.GetGenericTypeDefinition();\n\n\t\t\t\tif (genericType == openGenericType || genericType.IsSubclassOf(openGenericType))\n\t\t\t\t\treturn type.GetGenericArguments();\n\t\t\t}\n\n\t\t\t// clean\n\t\t\tgenericType = null;\n\n\t\t\t// check interfaces\n\t\t\tforeach (var _interface in type.GetInterfaces())\n\t\t\t{\n\t\t\t\tgenericType = _interface;\n\n\t\t\t\tif (!_interface.IsGenericType)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (!_interface.IsGenericTypeDefinition)\n\t\t\t\t\tgenericType = _interface.GetGenericTypeDefinition();\n\n\n\t\t\t\tif (genericType == openGenericType || genericType.IsSubclassOf(openGenericType))\n\t\t\t\t\treturn _interface.GetGenericArguments();\n\t\t\t}\n\n\n\t\t\tif (type.BaseType != null && type.BaseType != typeof (object))\n\t\t\t\treturn GetInstantiationArguments(type.BaseType, openGenericType);\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static string GetDataMemberName(object dataMemberAttribute)\n\t\t{\n\t\t\tif (dataMemberAttribute == null) throw new ArgumentNullException(\"dataMemberAttribute\");\n\n\t\t\tvar type = dataMemberAttribute.GetType();\n\t\t\tvar getName = default(MethodInfo);\n\n\t\t\tlock (GetNameMethods)\n\t\t\t{\n\t\t\t\tif (!GetNameMethods.TryGetValue(type, out getName))\n\t\t\t\t{\n\t\t\t\t\tgetName = type.GetMethod(\"get_Name\", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);\n\n\t\t\t\t\tif (getName == null || getName.ReturnType != typeof (string) || getName.GetParameters().Length != 0)\n\t\t\t\t\t\tgetName = null;\n\n\t\t\t\t\tif (getName == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar getNameProperty = type.GetProperty(\"Name\", BindingFlags.Instance | BindingFlags.Public, null, typeof (string),\n\t\t\t\t\t\t\tType.EmptyTypes, null);\n\t\t\t\t\t\tif (getNameProperty != null)\n\t\t\t\t\t\t\tgetName = getNameProperty.GetGetMethod(nonPublic: false);\n\t\t\t\t\t}\n\n\t\t\t\t\tGetNameMethods.Add(type, getName);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (getName != null)\n\t\t\t\treturn (string) getName.Invoke(dataMemberAttribute, EmptyArgs);\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n#if NET35 || UNITY\n\t\tpublic static Type GetTypeInfo(this Type type)\n\t\t{\n\t\t\treturn type;\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/ReflectionExtentions.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 5ce5b0d86a6b431f9a9542c4904b8e1e\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/SerializationContext.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.Serialization;\nusing System.Text;\nusing GameDevWare.Serialization.MessagePack;\nusing GameDevWare.Serialization.Serializers;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic sealed class SerializationContext\n\t{\n\t\tprivate readonly Dictionary<Type, TypeSerializer> serializers;\n\t\tprivate MessagePackExtensionTypeHandler extensionTypeHandler;\n\n\t\tpublic Stack<object> Hierarchy { get; private set; }\n\t\tpublic Stack<PathSegment> Path { get; private set; }\n\n\t\tpublic IFormatProvider Format { get; set; }\n\t\tpublic string[] DateTimeFormats { get; set; }\n\t\tpublic Encoding Encoding { get; set; }\n\n\t\tpublic Dictionary<Type, TypeSerializer> Serializers\n\t\t{\n\t\t\tget { return this.serializers; }\n\t\t\tset\n\t\t\t{\n\t\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\t\tforeach (var kv in value)\n\t\t\t\t\tthis.serializers[kv.Key] = kv.Value;\n\t\t\t}\n\t\t}\n\t\tpublic MessagePackExtensionTypeHandler ExtensionTypeHandler\n\t\t{\n\t\t\tget { return this.extensionTypeHandler; }\n\t\t\tset { if (value == null) throw new ArgumentNullException(\"value\"); this.extensionTypeHandler = value; }\n\t\t}\n\n\t\tpublic SerializationOptions Options { get; set; }\n\n\t\tpublic Func<Type, TypeSerializer> ObjectSerializerFactory { get; set; }\n\t\tpublic Func<Type, TypeSerializer> EnumSerializerFactory { get; set; }\n\t\tpublic Func<Type, TypeSerializer> DictionarySerializerFactory { get; set; }\n\t\tpublic Func<Type, TypeSerializer> ArraySerializerFactory { get; set; }\n\t\tpublic Func<Type, TypeSerializer> SerializerFactory { get; set; }\n\n\t\tpublic SerializationContext()\n\t\t{\n\t\t\tthis.Hierarchy = new Stack<object>();\n\t\t\tthis.Path = new Stack<PathSegment>();\n\n\t\t\tthis.Format = Json.DefaultFormat;\n\t\t\tthis.DateTimeFormats = Json.DefaultDateTimeFormats;\n\t\t\tthis.Encoding = Json.DefaultEncoding;\n\t\t\tthis.ExtensionTypeHandler = MsgPack.ExtensionTypeHandler;\n\n\t\t\tthis.serializers = Json.DefaultSerializers.ToDictionary(s => s.SerializedType);\n\t\t}\n\n\t\tpublic TypeSerializer GetSerializerForType(Type valueType)\n\t\t{\n\t\t\tif (valueType == null) throw new ArgumentNullException(\"valueType\");\n\n\t\t\tif (valueType.BaseType == typeof(MulticastDelegate) || valueType.BaseType == typeof(Delegate))\n\t\t\t\tthrow new InvalidOperationException(string.Format(\"Unable to serialize delegate type '{0}'.\", valueType));\n\n\t\t\tvar serializer = default(TypeSerializer);\n\t\t\tif (this.serializers.TryGetValue(valueType, out serializer))\n\t\t\t\treturn serializer;\n\n\t\t\tvar typeSerializerAttribute = valueType.GetCustomAttributes(typeof(TypeSerializerAttribute), inherit: false).FirstOrDefault() as TypeSerializerAttribute;\n\t\t\tif (typeSerializerAttribute != null)\n\t\t\t\tserializer = this.CreateCustomSerializer(valueType, typeSerializerAttribute);\n\t\t\telse if (valueType.IsEnum)\n\t\t\t\tserializer = this.CreateEnumSerializer(valueType);\n\t\t\telse if (typeof(IDictionary).IsAssignableFrom(valueType) || valueType.IsInstantiationOf(typeof(IDictionary<,>)))\n\t\t\t\tserializer = this.CreateDictionarySerializer(valueType);\n\t\t\telse if (valueType.IsArray || typeof(IEnumerable).IsAssignableFrom(valueType))\n\t\t\t\tserializer = this.CreateArraySerializer(valueType);\n\t\t\telse\n\t\t\t\tserializer = (this.SerializerFactory != null ? this.SerializerFactory(valueType) : null) ?? this.CreateObjectSerializer(valueType);\n\n\t\t\tthis.serializers.Add(valueType, serializer);\n\t\t\treturn serializer;\n\t\t}\n\n\t\tprivate TypeSerializer CreateDictionarySerializer(Type valueType)\n\t\t{\n\t\t\tif (this.DictionarySerializerFactory != null)\n\t\t\t\treturn this.DictionarySerializerFactory(valueType);\n\t\t\telse\n\t\t\t\treturn new DictionarySerializer(valueType);\n\t\t}\n\t\tprivate TypeSerializer CreateEnumSerializer(Type valueType)\n\t\t{\n\t\t\tif (this.EnumSerializerFactory != null)\n\t\t\t\treturn this.EnumSerializerFactory(valueType);\n\t\t\telse\n\t\t\t\treturn new EnumSerializer(valueType);\n\t\t}\n\t\tprivate TypeSerializer CreateArraySerializer(Type valueType)\n\t\t{\n\t\t\tif (this.ArraySerializerFactory != null)\n\t\t\t\treturn this.ArraySerializerFactory(valueType);\n\t\t\telse\n\t\t\t\treturn new ArraySerializer(valueType);\n\t\t}\n\t\tprivate TypeSerializer CreateObjectSerializer(Type valueType)\n\t\t{\n\t\t\tif (this.ObjectSerializerFactory != null)\n\t\t\t\treturn this.ObjectSerializerFactory(valueType);\n\t\t\telse\n\t\t\t\treturn new ObjectSerializer(this, valueType);\n\t\t}\n\t\tprivate TypeSerializer CreateCustomSerializer(Type valueType, TypeSerializerAttribute typeSerializerAttribute)\n\t\t{\n\t\t\tvar serializerType = typeSerializerAttribute.SerializerType;\n\n\t\t\tvar typeCtr = serializerType.GetConstructor(new[] { typeof(Type) });\n\t\t\tif (typeCtr != null)\n\t\t\t\treturn (TypeSerializer)typeCtr.Invoke(new object[] { valueType });\n\n\t\t\tvar ctxTypeCtr = serializerType.GetConstructor(new[] { typeof(SerializationContext), typeof(Type) });\n\t\t\tif (ctxTypeCtr != null)\n\t\t\t\treturn (TypeSerializer)ctxTypeCtr.Invoke(new object[] { this, valueType });\n\n\t\t\tvar ctxCtr = serializerType.GetConstructor(new[] { typeof(SerializationContext) });\n\t\t\tif (ctxCtr != null)\n\t\t\t\treturn (TypeSerializer)ctxCtr.Invoke(new object[] { this });\n\n\t\t\treturn (TypeSerializer)Activator.CreateInstance(serializerType);\n\t\t}\n\n\t\tpublic Type GetType(string name, bool throwOnError, bool ignoreCase)\n\t\t{\n\t\t\treturn Type.GetType(name, throwOnError, ignoreCase);\n\t\t}\n\t\tpublic Type GetType(string name, bool throwOnError)\n\t\t{\n\t\t\treturn Type.GetType(name, throwOnError);\n\t\t}\n\t\tpublic Type GetType(string name)\n\t\t{\n\t\t\treturn Type.GetType(name);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reset serialization context for future re-use. Clears <see cref=\"Hierarchy\"/> and <see cref=\"Path\"/> collections.\n\t\t/// </summary>\n\t\tpublic void Reset()\n\t\t{\n\t\t\tthis.Hierarchy.Clear();\n\t\t\tthis.Path.Clear();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Get object hierarchy (arrays/objects) path to current reader position.\n\t\t/// </summary>\n\t\t/// <returns></returns>\n\t\tpublic string GetPath()\n\t\t{\n\t\t\tvar path = new StringBuilder();\n\t\t\tforeach (var segment in this.Path.Reverse())\n\t\t\t{\n\t\t\t\tvar segmentString = segment.ToString();\n\t\t\t\tif (string.IsNullOrEmpty(segmentString))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpath.Append(segmentString);\n\t\t\t\tpath.Append(\".\");\n\t\t\t}\n\n\t\t\tif (path.Length > 0)\n\t\t\t{\n\t\t\t\tpath.Length--;\n\t\t\t}\n\n\t\t\treturn path.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/SerializationContext.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 8d8d56843e2f47c58582e1025a2587dc\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/SerializationOptions.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\t[Flags]\n\tpublic enum SerializationOptions\n\t{\n\t\tNone = 0,\n\t\tSuppressTypeInformation = 0x1 << 1,\n\t\tPrettyPrint = 0x1 << 2,\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/SerializationOptions.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 5838dd2a7ce14a40a9439645c1fe216f\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/ArraySerializer.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class ArraySerializer : TypeSerializer\n\t{\n\t\tprivate readonly Type arrayType;\n\t\tprivate readonly Type instantiatedArrayType;\n\t\tprivate readonly Type elementType;\n\n\t\tpublic override Type SerializedType { get { return this.arrayType; } }\n\n\t\tpublic ArraySerializer(Type enumerableType)\n\t\t{\n\t\t\tif (enumerableType == null) throw new ArgumentNullException(\"enumerableType\");\n\n\t\t\tthis.arrayType =\n\t\t\tthis.instantiatedArrayType = enumerableType;\n\t\t\tthis.elementType = this.GetElementType(arrayType);\n\n\t\t\tif (this.elementType == null) throw JsonSerializationException.TypeIsNotValid(this.GetType(), \"be enumerable\");\n\n\t\t\tif (this.arrayType == typeof(IList) || this.arrayType == typeof(ICollection) || this.arrayType == typeof(IEnumerable))\n\t\t\t\tthis.instantiatedArrayType = typeof(ArrayList);\n\t\t\telse if (arrayType.IsInterface && arrayType.IsGenericType && (arrayType.GetGenericTypeDefinition() == typeof(IList<>) || arrayType.GetGenericTypeDefinition() == typeof(ICollection<>) || arrayType.GetGenericTypeDefinition() == typeof(IEnumerable<>)))\n\t\t\t\tthis.instantiatedArrayType = typeof(List<>).MakeGenericType(this.elementType);\n\t\t}\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar container = new ArrayList();\n\t\t\tif (reader.Token != JsonToken.BeginArray)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.BeginArray);\n\n\t\t\treader.Context.Hierarchy.Push(container);\n\t\t\tvar i = 0;\n\t\t\twhile (reader.NextToken() && reader.Token != JsonToken.EndOfArray)\n\t\t\t{\n\t\t\t\treader.Context.Path.Push(new PathSegment(i++));\n\n\t\t\t\tvar value = reader.ReadValue(this.elementType, false);\n\t\t\t\tcontainer.Add(value);\n\n\t\t\t\treader.Context.Path.Pop();\n\t\t\t}\n\t\t\treader.Context.Hierarchy.Pop();\n\n\t\t\tif (reader.IsEndOfStream())\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.EndOfArray);\n\n\t\t\tif (this.instantiatedArrayType == typeof(ArrayList))\n\t\t\t\treturn container;\n\t\t\telse if (this.instantiatedArrayType.IsArray)\n\t\t\t\treturn container.ToArray(this.elementType);\n\t\t\telse\n\t\t\t\treturn Activator.CreateInstance(this.instantiatedArrayType, container.ToArray(this.elementType));\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar size = 0;\n\t\t\tif (value is ICollection)\n\t\t\t\tsize = ((ICollection)value).Count;\n\t\t\telse\n\t\t\t\tsize = ((IEnumerable)value).Cast<object>().Count();\n\n\t\t\twriter.WriteArrayBegin(size);\n\t\t\tvar i = 0;\n\t\t\tforeach (var item in (IEnumerable)value)\n\t\t\t{\n\t\t\t\twriter.Context.Path.Push(new PathSegment(i++));\n\t\t\t\twriter.WriteValue(item, this.elementType);\n\t\t\t\twriter.Context.Path.Pop();\n\t\t\t}\n\t\t\twriter.WriteArrayEnd();\n\t\t}\n\n\t\tprivate Type GetElementType(Type arrayType)\n\t\t{\n\t\t\tif (arrayType == null) throw new ArgumentNullException(\"arrayType\");\n\n\n\t\t\tvar elementType = (Type)null;\n\t\t\tif (arrayType.IsArray)\n\t\t\t{\n\t\t\t\telementType = arrayType.GetElementType();\n\t\t\t\treturn elementType;\n\t\t\t}\n\n\t\t\tif (arrayType.IsInstantiationOf(typeof(IEnumerable<>)))\n\t\t\t{\n\t\t\t\tif (arrayType.HasMultipleInstantiations(typeof(IEnumerable<>)))\n\t\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(this.GetType(), \"have only one generic IEnumerable interface\");\n\n\t\t\t\telementType = arrayType.GetInstantiationArguments(typeof(IEnumerable<>))[0];\n\t\t\t}\n\n\t\t\tif (elementType == null && typeof(IEnumerable).IsAssignableFrom(arrayType))\n\t\t\t\telementType = typeof(object);\n\t\t\telse if (elementType == null)\n\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(this.GetType(), \"be enumerable\");\n\n\t\t\treturn elementType;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"array of {1}, {0}\", this.arrayType, this.elementType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/ArraySerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 06ca5f3ec70842a98c968db9509b25b9\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/BinarySerializer.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing GameDevWare.Serialization.MessagePack;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class BinarySerializer : TypeSerializer\n\t{\n\t\tpublic static readonly BinarySerializer Instance = new BinarySerializer();\n\n\t\tpublic override Type SerializedType { get { return typeof(byte[]); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tif (reader.RawValue is byte[])\n\t\t\t{\n\t\t\t\treturn reader.RawValue;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar value = reader.RawValue as string;\n\t\t\t\tif (value == null)\n\t\t\t\t\treturn null;\n\n\t\t\t\tvar buffer = Convert.FromBase64String(value);\n\t\t\t\treturn buffer;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\twriter.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (value != null && value is byte[] == false) throw JsonSerializationException.TypeIsNotValid(this.GetType(), \"be array of bytes\");\n\n\t\t\tvar bytes = (byte[])value;\n\t\t\tif (writer is MsgPackWriter)\n\t\t\t{\n\t\t\t\t((MsgPackWriter)writer).Write(bytes);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar base64String = Convert.ToBase64String(bytes);\n\t\t\t\twriter.WriteString(base64String);\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"byte[] as Base64\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/BinarySerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 31ebab347e1749c3aecc94f559bcdc31\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/BoundsSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class BoundsSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Bounds); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Bounds();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tif (memberName == \"center\")\n\t\t\t\t\tvalue.center = (Vector3)reader.ReadValue(typeof(Vector3));\n\t\t\t\telse if (memberName == \"extents\")\n\t\t\t\t\tvalue.extents = (Vector3)reader.ReadValue(typeof(Vector3));\n\t\t\t\telse\n\t\t\t\t\treader.ReadValue(typeof(object));\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar bounds = (Bounds)value;\n\t\t\twriter.WriteObjectBegin(2);\n\t\t\twriter.WriteMember(\"center\");\n\t\t\twriter.WriteValue(bounds.center, typeof(Vector3));\n\t\t\twriter.WriteMember(\"extents\");\n\t\t\twriter.WriteValue(bounds.extents, typeof(Vector3));\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/BoundsSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: bc132289c33349ff9bd5abd3d12a75d6\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DateTimeOffsetSerializer.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Globalization;\nusing System.Linq;\nusing System.Runtime.Serialization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class DateTimeOffsetSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(DateTimeOffset); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Value.Raw is DateTimeOffset)\n\t\t\t\treturn reader.Value.Raw;\n\t\t\telse if (reader.Token == JsonToken.DateTime || reader.Value.Raw is DateTime)\n\t\t\t\treturn new DateTimeOffset(reader.Value.AsDateTime);\n\n\t\t\tvar dateTimeOffsetStr = reader.ReadString(false);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar value = default(DateTimeOffset);\n\t\t\t\tif (!DateTimeOffset.TryParse(dateTimeOffsetStr, reader.Context.Format, DateTimeStyles.RoundtripKind, out value))\n\t\t\t\t\tvalue = DateTimeOffset.ParseExact(dateTimeOffsetStr, reader.Context.DateTimeFormats, reader.Context.Format, DateTimeStyles.RoundtripKind);\n\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\tcatch (FormatException fe)\n\t\t\t{\n\t\t\t\tthrow new SerializationException(string.Format(\"Failed to parse date '{0}' in with pattern '{1}'.\", dateTimeOffsetStr, reader.Context.DateTimeFormats[0]), fe);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar dateTimeOffset = (DateTimeOffset)value;\n\t\t\twriter.Write(dateTimeOffset);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DateTimeOffsetSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: c4ce03616aa546889bd2f53159324084\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DateTimeSerializer.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Globalization;\nusing System.Linq;\nusing System.Runtime.Serialization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class DateTimeSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(DateTime); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.DateTime || reader.RawValue is DateTime)\n\t\t\t\treturn reader.Value.AsDateTime;\n\n\t\t\tvar dateTimeStr = reader.ReadString(false);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar value = default(DateTime);\n\t\t\t\tif (!DateTime.TryParse(dateTimeStr, reader.Context.Format, DateTimeStyles.RoundtripKind, out value))\n\t\t\t\t\tvalue = DateTime.ParseExact(dateTimeStr, reader.Context.DateTimeFormats, reader.Context.Format, DateTimeStyles.RoundtripKind);\n\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\tcatch (FormatException fe)\n\t\t\t{\n\t\t\t\tthrow new SerializationException(string.Format(\"Failed to parse date '{0}' in with pattern '{1}'.\", dateTimeStr, reader.Context.DateTimeFormats[0]), fe);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar dataTime = (DateTime)value;\n\t\t\twriter.Write(dataTime);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DateTimeSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 313eb481f0f545958d48aa9bc511a541\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DictionaryEntrySerializer.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections;\nusing System.Runtime.Serialization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class DictionaryEntrySerializer : TypeSerializer\n\t{\n\t\tpublic const string KEY_MEMBER_NAME = \"Key\";\n\t\tpublic const string VALUE_MEMBER_NAME = \"Value\";\n\n\t\tpublic override Type SerializedType { get { return typeof(DictionaryEntry); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.BeginArray)\n\t\t\t{\n\t\t\t\tvar entry = new DictionaryEntry();\n\t\t\t\treader.ReadArrayBegin();\n\t\t\t\tentry.Key = reader.ReadValue(typeof(object));\n\t\t\t\tentry.Value = reader.ReadValue(typeof(object));\n\t\t\t\treader.ReadArrayEnd(nextToken: false);\n\t\t\t\treturn entry;\n\t\t\t}\n\t\t\telse if (reader.Token == JsonToken.BeginObject)\n\t\t\t{\n\t\t\t\tvar entry = new DictionaryEntry();\n\t\t\t\treader.ReadObjectBegin();\n\t\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t\t{\n\t\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\t\tswitch (memberName)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEY_MEMBER_NAME:\n\t\t\t\t\t\t\tentry.Key = reader.ReadValue(typeof(object));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase VALUE_MEMBER_NAME:\n\t\t\t\t\t\t\tentry.Value = reader.ReadValue(typeof(object));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ObjectSerializer.TYPE_MEMBER_NAME:\n\t\t\t\t\t\t\treader.ReadValue(typeof(object));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new SerializationException(string.Format(\"Unknown member found '{0}' while '{1}' or '{2}' are expected.\", memberName, KEY_MEMBER_NAME, VALUE_MEMBER_NAME));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\t\treturn entry;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.BeginObject, JsonToken.BeginArray);\n\t\t\t}\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar entry = (DictionaryEntry)value;\n\t\t\twriter.WriteObjectBegin(2);\n\t\t\twriter.WriteMember(KEY_MEMBER_NAME);\n\t\t\twriter.WriteValue(entry.Key, typeof(object));\n\t\t\twriter.WriteMember(VALUE_MEMBER_NAME);\n\t\t\twriter.WriteValue(entry.Value, typeof(object));\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DictionaryEntrySerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: f4b2e86264a34d819b457cf3eebf2318\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DictionarySerializer.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.Serialization;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class DictionarySerializer : TypeSerializer\n\t{\n\t\tprivate readonly Type dictionaryType;\n\t\tprivate readonly Type instantiatedDictionaryType;\n\t\tprivate readonly Type keyType;\n\t\tprivate readonly Type valueType;\n\t\tprivate readonly bool isStringKeyType;\n\n\t\tpublic override Type SerializedType { get { return this.dictionaryType; } }\n\n\t\tpublic DictionarySerializer(Type dictionaryType)\n\t\t{\n\t\t\tif (dictionaryType == null)\n\t\t\t\tthrow new ArgumentNullException(\"dictionaryType\");\n\n\t\t\tthis.dictionaryType =\n\t\t\tthis.instantiatedDictionaryType = dictionaryType;\n\t\t\tthis.keyType = typeof(object);\n\t\t\tthis.valueType = typeof(object);\n\n\t\t\tif (dictionaryType.HasMultipleInstantiations(typeof(IDictionary<,>)))\n\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(this.GetType(), \"have only one generic IDictionary<,> interface\");\n\n\n\t\t\tif (dictionaryType.IsInstantiationOf(typeof(IDictionary<,>)))\n\t\t\t{\n\t\t\t\tvar genArgs = dictionaryType.GetInstantiationArguments(typeof(IDictionary<,>));\n\t\t\t\tthis.keyType = genArgs[0];\n\t\t\t\tthis.valueType = genArgs[1];\n\n\t\t\t\tif (dictionaryType.IsInterface && dictionaryType.IsGenericType && dictionaryType.GetGenericTypeDefinition() == typeof(IDictionary<,>))\n\t\t\t\t\tthis.instantiatedDictionaryType = typeof(Dictionary<,>).MakeGenericType(genArgs);\n\t\t\t\telse if (typeof(IDictionary).IsAssignableFrom(dictionaryType) == false)\n\t\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(this.GetType(), \"should implement IDictionary interface\");\n\t\t\t}\n\t\t\telse if (typeof(IDictionary).IsAssignableFrom(dictionaryType))\n\t\t\t{\n\t\t\t\tif (dictionaryType == typeof(IDictionary))\n\t\t\t\t{\n\t\t\t\t\tthis.instantiatedDictionaryType = typeof(IndexedDictionary<string, object>);\n\t\t\t\t\tthis.keyType = typeof(string);\n\t\t\t\t\tthis.valueType = typeof(object);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(this.GetType(), \"should implement IDictionary interface\");\n\t\t\t}\n\n\t\t\tthis.isStringKeyType = this.keyType == typeof(string);\n\t\t}\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tvar container = new List<DictionaryEntry>();\n\t\t\treader.Context.Hierarchy.Push(container);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (reader.Token == JsonToken.BeginArray)\n\t\t\t\t{\n\t\t\t\t\treader.ReadArrayBegin();\n\t\t\t\t\twhile (reader.Token != JsonToken.EndOfArray)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar entry = default(DictionaryEntry);\n\n\t\t\t\t\t\tif (reader.Token == JsonToken.BeginArray)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treader.ReadArrayBegin();\n\t\t\t\t\t\t\ttry { entry.Key = reader.ReadValue(this.keyType); }\n\t\t\t\t\t\t\tcatch (Exception e) { throw new SerializationException(string.Format(\"Failed to read '{0}' key of dictionary: {1}\\r\\nMore detailed information in inner exception.\", this.keyType.Name, e.Message), e); }\n\t\t\t\t\t\t\treader.Context.Path.Push(new PathSegment(entry.Key));\n\t\t\t\t\t\t\ttry { entry.Value = reader.ReadValue(this.valueType); }\n\t\t\t\t\t\t\tcatch (Exception e) { throw new SerializationException(string.Format(\"Failed to read '{0}' value for key '{1}' in dictionary: {2}\\r\\nMore detailed information in inner exception.\", this.valueType.Name, entry.Key, e.Message), e); }\n\t\t\t\t\t\t\treader.Context.Path.Pop();\n\t\t\t\t\t\t\treader.ReadArrayEnd();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treader.ReadObjectBegin();\n\t\t\t\t\t\t\tvar keyIsPushed = false;\n\t\t\t\t\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\t\t\t\t\tswitch (memberName)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase DictionaryEntrySerializer.KEY_MEMBER_NAME:\n\t\t\t\t\t\t\t\t\t\ttry { entry.Key = reader.ReadValue(this.keyType); }\n\t\t\t\t\t\t\t\t\t\tcatch (Exception e) { throw new SerializationException(string.Format(\"Failed to read '{0}' key of dictionary: {1}\\r\\nMore detailed information in inner exception.\", this.keyType.Name, e.Message), e); }\n\t\t\t\t\t\t\t\t\t\tif (!keyIsPushed)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\treader.Context.Path.Push(new PathSegment(entry.Key));\n\t\t\t\t\t\t\t\t\t\t\tkeyIsPushed = true;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase DictionaryEntrySerializer.VALUE_MEMBER_NAME:\n\t\t\t\t\t\t\t\t\t\ttry { entry.Value = reader.ReadValue(this.valueType); }\n\t\t\t\t\t\t\t\t\t\tcatch (Exception e) { throw new SerializationException(string.Format(\"Failed to read '{0}' value for key '{1}' in dictionary: {2}\\r\\nMore detailed information in inner exception.\", this.valueType.Name, entry.Key ?? \"<unknown>\", e.Message), e); }\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase ObjectSerializer.TYPE_MEMBER_NAME:\n\t\t\t\t\t\t\t\t\t\treader.ReadValue(typeof(object));\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\tthrow new SerializationException(string.Format(\"Unknown member found '{0}' in dictionary entry while '{1}' or '{2}' are expected.\", memberName, DictionaryEntrySerializer.KEY_MEMBER_NAME, DictionaryEntrySerializer.VALUE_MEMBER_NAME));\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (keyIsPushed)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treader.Context.Path.Pop();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treader.ReadObjectEnd();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontainer.Add(entry);\n\t\t\t\t\t}\n\t\t\t\t\treader.ReadArrayEnd(nextToken: false);\n\t\t\t\t}\n\t\t\t\telse if (reader.Token == JsonToken.BeginObject)\n\t\t\t\t{\n\t\t\t\t\treader.ReadObjectBegin();\n\t\t\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar entry = default(DictionaryEntry);\n\n\t\t\t\t\t\ttry { entry.Key = reader.ReadValue(this.keyType); }\n\t\t\t\t\t\tcatch (Exception e) { throw new SerializationException(string.Format(\"Failed to read '{0}' key of dictionary: {1}\\r\\nMore detailed information in inner exception.\", this.keyType.Name, e.Message), e); }\n\t\t\t\t\t\treader.Context.Path.Push(new PathSegment(entry.Key));\n\n\t\t\t\t\t\ttry { entry.Value = reader.ReadValue(this.valueType); }\n\t\t\t\t\t\tcatch (Exception e) { throw new SerializationException(string.Format(\"Failed to read '{0}' value for key '{1}' in dictionary: {2}\\r\\nMore detailed information in inner exception.\", this.valueType.Name, entry.Key, e.Message), e); }\n\n\t\t\t\t\t\treader.Context.Path.Pop();\n\t\t\t\t\t\tcontainer.Add(entry);\n\t\t\t\t\t}\n\t\t\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.BeginObject, JsonToken.BeginArray);\n\t\t\t\t}\n\n\t\t\t\tvar dictionary = (IDictionary)Activator.CreateInstance(this.instantiatedDictionaryType);\n\t\t\t\tforeach (var kv in container)\n\t\t\t\t{\n\t\t\t\t\tvar key = kv.Key;\n\t\t\t\t\tvar value = kv.Value;\n\n\t\t\t\t\tif (key.GetType() != this.keyType && this.keyType != typeof(object))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (this.keyType.IsEnum)\n\t\t\t\t\t\t\tkey = Enum.Parse(this.keyType, Convert.ToString(key));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tkey = Convert.ChangeType(key, this.keyType);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (dictionary.Contains(key))\n\t\t\t\t\t\tdictionary.Remove(key);\n\n\t\t\t\t\tdictionary.Add(key, value);\n\t\t\t\t}\n\n\t\t\t\treturn dictionary;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\treader.Context.Hierarchy.Pop();\n\t\t\t}\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar dictionary = (IDictionary)value;\n\t\t\t// ReSharper disable PossibleMultipleEnumeration\n\t\t\twriter.Context.Hierarchy.Push(value);\n\t\t\t// object\n\t\t\tif (this.isStringKeyType)\n\t\t\t{\n\t\t\t\twriter.WriteObjectBegin(dictionary.Count);\n\t\t\t\tforeach (DictionaryEntry pair in dictionary)\n\t\t\t\t{\n\t\t\t\t\tvar keyStr = Convert.ToString(pair.Key, writer.Context.Format);\n\t\t\t\t\twriter.Context.Path.Push(new PathSegment(keyStr));\n\n\t\t\t\t\t// key\n\t\t\t\t\twriter.WriteMember(keyStr);\n\t\t\t\t\t// value\n\t\t\t\t\twriter.WriteValue(pair.Value, this.valueType);\n\n\t\t\t\t\twriter.Context.Path.Pop();\n\t\t\t\t}\n\t\t\t\twriter.WriteObjectEnd();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.WriteArrayBegin(dictionary.Count);\n\t\t\t\tforeach (DictionaryEntry pair in dictionary)\n\t\t\t\t{\n\t\t\t\t\twriter.Context.Path.Push(new PathSegment(pair.Key));\n\t\t\t\t\twriter.WriteArrayBegin(2);\n\t\t\t\t\twriter.WriteValue(pair.Key, this.keyType);\n\t\t\t\t\twriter.WriteValue(pair.Value, this.valueType);\n\t\t\t\t\twriter.WriteArrayEnd();\n\t\t\t\t\twriter.Context.Path.Pop();\n\t\t\t\t}\n\t\t\t\twriter.WriteArrayEnd();\n\t\t\t}\n\t\t\t// ReSharper restore PossibleMultipleEnumeration\n\n\t\t\twriter.Context.Hierarchy.Pop();\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"dictionary of {1}:{2}, {0}\", this.dictionaryType, this.keyType, this.valueType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/DictionarySerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 13a732fa56444620a58134388e9cb921\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/EnumNumberSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class EnumNumberSerializer : TypeSerializer\n\t{\n\t\tprivate readonly Type enumType;\n\t\tprivate readonly Type enumBaseType;\n\n\t\tpublic override Type SerializedType { get { return this.enumType; } }\n\n\t\tpublic EnumNumberSerializer(Type enumType)\n\t\t{\n\t\t\tif (enumType == null) throw new ArgumentNullException(\"enumType\");\n\t\t\tif (!enumType.IsEnum) throw JsonSerializationException.TypeIsNotValid(this.GetType(), \"be a Enum\");\n\n\t\t\tthis.enumType = enumType;\n\t\t\tthis.enumBaseType = Enum.GetUnderlyingType(enumType);\n\t\t}\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.StringLiteral)\n\t\t\t\treturn Enum.Parse(this.enumType, reader.ReadString(false), true);\n\t\t\telse if (reader.Token == JsonToken.Number)\n\t\t\t\treturn Enum.ToObject(this.enumType, reader.ReadValue(this.enumBaseType, false));\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.Number, JsonToken.StringLiteral);\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\twriter.WriteValue(Convert.ChangeType(value, this.enumBaseType), this.enumBaseType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/EnumNumberSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: c69cddac8b674579a85f39be4d0a6869\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/EnumSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class EnumSerializer : TypeSerializer\n\t{\n\t\tprivate readonly Type enumType;\n\t\tprivate readonly Type enumBaseType;\n\n\t\tpublic override Type SerializedType { get { return this.enumType; } }\n\n\t\tpublic EnumSerializer(Type enumType)\n\t\t{\n\t\t\tif (enumType == null) throw new ArgumentNullException(\"enumType\");\n\t\t\tif (!enumType.IsEnum) throw JsonSerializationException.TypeIsNotValid(this.GetType(), \"be a Enum\");\n\n\t\t\tthis.enumType = enumType;\n\t\t\tthis.enumBaseType = Enum.GetUnderlyingType(enumType);\n\t\t}\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.StringLiteral)\n\t\t\t\treturn Enum.Parse(this.enumType, reader.ReadString(false), true);\n\t\t\telse if (reader.Token == JsonToken.Number)\n\t\t\t\treturn Enum.ToObject(this.enumType, reader.ReadValue(this.enumBaseType, false));\n\t\t\telse\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.Number, JsonToken.StringLiteral);\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar valueStr = Convert.ToString(value, writer.Context.Format);\n\t\t\twriter.WriteString(valueStr);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/EnumSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 767beb9929ef47068dd78d4e4d82c6c9\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/GuidSerializer.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing GameDevWare.Serialization.MessagePack;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class GuidSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Guid); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tvar guidStr = reader.ReadString(false);\n\t\t\tvar value = new Guid(guidStr);\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar messagePackWriter = writer as MsgPackWriter;\n\t\t\tif (messagePackWriter != null)\n\t\t\t{\n\t\t\t\t// try to write it as Message Pack extension type\n\t\t\t\tvar extensionType = default(sbyte);\n\t\t\t\tvar buffer = messagePackWriter.GetWriteBuffer();\n\t\t\t\tif (messagePackWriter.Context.ExtensionTypeHandler.TryWrite(value, out extensionType, ref buffer))\n\t\t\t\t{\n\t\t\t\t\tmessagePackWriter.Write(extensionType, buffer);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// if not, continue default serialization\n\t\t\t}\n\n\t\t\tvar guid = (Guid)value;\n\t\t\tvar guidStr = guid.ToString();\n\t\t\twriter.Write(guidStr);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/GuidSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: d6721c41f669421289be40c0416e683c\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Matrix4x4Serializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class Matrix4x4Serializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Matrix4x4); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Matrix4x4();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tswitch (memberName)\n\t\t\t\t{\n\t\t\t\t\tcase \"m00\": value.m00 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m10\": value.m10 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m20\": value.m20 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m30\": value.m30 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m01\": value.m01 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m11\": value.m11 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m21\": value.m21 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m31\": value.m31 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m02\": value.m02 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m12\": value.m12 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m22\": value.m22 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m32\": value.m32 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m03\": value.m03 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m13\": value.m13 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m23\": value.m23 = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"m33\": value.m33 = reader.ReadSingle(); break;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treader.ReadValue(typeof(object));\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar matrix = (Matrix4x4)value;\n\t\t\twriter.WriteObjectBegin(16);\n\t\t\twriter.WriteMember(\"m00\");\n\t\t\twriter.Write(matrix.m00);\n\t\t\twriter.WriteMember(\"m10\");\n\t\t\twriter.Write(matrix.m10);\n\t\t\twriter.WriteMember(\"m20\");\n\t\t\twriter.Write(matrix.m20);\n\t\t\twriter.WriteMember(\"m30\");\n\t\t\twriter.Write(matrix.m30);\n\t\t\twriter.WriteMember(\"m01\");\n\t\t\twriter.Write(matrix.m01);\n\t\t\twriter.WriteMember(\"m11\");\n\t\t\twriter.Write(matrix.m11);\n\t\t\twriter.WriteMember(\"m21\");\n\t\t\twriter.Write(matrix.m21);\n\t\t\twriter.WriteMember(\"m31\");\n\t\t\twriter.Write(matrix.m31);\n\t\t\twriter.WriteMember(\"m02\");\n\t\t\twriter.Write(matrix.m02);\n\t\t\twriter.WriteMember(\"m12\");\n\t\t\twriter.Write(matrix.m12);\n\t\t\twriter.WriteMember(\"m22\");\n\t\t\twriter.Write(matrix.m22);\n\t\t\twriter.WriteMember(\"m32\");\n\t\t\twriter.Write(matrix.m32);\n\t\t\twriter.WriteMember(\"m03\");\n\t\t\twriter.Write(matrix.m03);\n\t\t\twriter.WriteMember(\"m13\");\n\t\t\twriter.Write(matrix.m13);\n\t\t\twriter.WriteMember(\"m23\");\n\t\t\twriter.Write(matrix.m23);\n\t\t\twriter.WriteMember(\"m33\");\n\t\t\twriter.Write(matrix.m33);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Matrix4x4Serializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 47390c8c743d4b078b66766035eaf27c\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/MsgPackExtensionTypeSerializer.cs",
    "content": "/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Globalization;\nusing GameDevWare.Serialization.MessagePack;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class MsgPackExtensionTypeSerializer : TypeSerializer\n\t{\n\t\tprivate const string DATA_MEMBER_NAME = \"$data\";\n\t\tprivate const string TYPE_MEMBER_NAME = \"$type\";\n\n\t\t/// <inheritdoc />\n\t\tpublic override Type SerializedType { get { return typeof(MessagePackExtensionType); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\telse if (reader.RawValue is MessagePackExtensionType)\n\t\t\t{\n\t\t\t\treturn (MessagePackExtensionType)reader.RawValue;\n\t\t\t}\n\t\t\telse if (reader.RawValue is byte[])\n\t\t\t{\n\t\t\t\treturn new MessagePackExtensionType((byte[])reader.RawValue);\n\t\t\t}\n\t\t\telse if (reader.RawValue is string)\n\t\t\t{\n\t\t\t\treturn new MessagePackExtensionType(Convert.FromBase64String(reader.Value.AsString));\n\t\t\t}\n\n\t\t\t// { \"$binary\" : \"<bindata>\", \"$type\" : \"<t>\" }\n\t\t\t// http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON\n\n\t\t\treader.ReadObjectBegin();\n\t\t\tvar base64Binary = default(string);\n\t\t\tvar subtypeHex = default(string);\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar member = reader.ReadMember();\n\t\t\t\tswitch (member)\n\t\t\t\t{\n\t\t\t\t\tcase DATA_MEMBER_NAME:\n\t\t\t\t\t\tbase64Binary = reader.ReadString();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TYPE_MEMBER_NAME:\n\t\t\t\t\t\tsubtypeHex = reader.ReadString();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treader.ReadValue(typeof(object)); // skip value\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\n\t\t\tif (subtypeHex == null) subtypeHex = \"0\";\n\t\t\tif (base64Binary == null) base64Binary = \"\";\n\n\t\t\tvar binaryType = unchecked((sbyte)byte.Parse(subtypeHex, NumberStyles.HexNumber));\n\t\t\tvar binary = Convert.FromBase64String(base64Binary);\n\n\t\t\tvar value = new MessagePackExtensionType(binaryType, binary);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\twriter.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar extensionType = (MessagePackExtensionType)value;\n\n\t\t\tvar msgPackWriter = writer as MsgPackWriter;\n\t\t\tif (msgPackWriter != null)\n\t\t\t{\n\t\t\t\tmsgPackWriter.Write(extensionType.Type, extensionType.ToArraySegment());\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twriter.WriteObjectBegin(2);\n\t\t\twriter.WriteMember(DATA_MEMBER_NAME);\n\t\t\twriter.WriteString(extensionType.ToBase64());\n\t\t\twriter.WriteMember(TYPE_MEMBER_NAME);\n\t\t\twriter.Write(unchecked((byte)extensionType.Type).ToString(\"X2\"));\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/MsgPackExtensionTypeSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 5e091ddc6ecc49c4a1f563cc24cb2aaf\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/MsgPackTimestampSerializer.cs",
    "content": "using System;\nusing GameDevWare.Serialization.MessagePack;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic class MsgPackTimestampSerializer : TypeSerializer\n\t{\n\t\tprivate const string SECONDS_MEMBER_NAME = \"$seconds\";\n\t\tprivate const string NANO_SECONDS_MEMBER_NAME = \"$nanoSeconds\";\n\n\t\t/// <inheritdoc />\n\t\tpublic override Type SerializedType { get { return typeof(MessagePackTimestamp); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader.RawValue is MessagePackTimestamp)\n\t\t\t{\n\t\t\t\treturn (MessagePackTimestamp)reader.Value.Raw;\n\t\t\t}\n\t\t\telse if (reader.Token == JsonToken.Null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treader.ReadObjectBegin();\n\t\t\tvar seconds = default(long);\n\t\t\tvar nanoSeconds = default(uint);\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar member = reader.ReadMember();\n\t\t\t\tswitch (member)\n\t\t\t\t{\n\t\t\t\t\tcase SECONDS_MEMBER_NAME:\n\t\t\t\t\t\tseconds = reader.ReadInt64();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NANO_SECONDS_MEMBER_NAME:\n\t\t\t\t\t\tseconds = reader.ReadUInt32();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treader.ReadValue(typeof(object)); // skip value\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treader.ReadObjectEnd(false);\n\n\t\t\tvar value = new MessagePackTimestamp(seconds, nanoSeconds);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\twriter.WriteNull();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar messagePackWriter = writer as MsgPackWriter;\n\t\t\tif (messagePackWriter != null)\n\t\t\t{\n\t\t\t\tvar extensionType = default(sbyte);\n\t\t\t\tvar buffer = messagePackWriter.GetWriteBuffer();\n\t\t\t\tif (messagePackWriter.Context.ExtensionTypeHandler.TryWrite(value, out extensionType, ref buffer))\n\t\t\t\t{\n\t\t\t\t\tmessagePackWriter.Write(extensionType, buffer);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar timeStamp = (MessagePackTimestamp)value;\n\t\t\twriter.WriteObjectBegin(2);\n\t\t\twriter.WriteMember(SECONDS_MEMBER_NAME);\n\t\t\twriter.Write(timeStamp.Seconds);\n\t\t\twriter.WriteMember(NANO_SECONDS_MEMBER_NAME);\n\t\t\twriter.Write(timeStamp.NanoSeconds);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/MsgPackTimestampSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 958711d50492492aa2bffb7dadf13927\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.Serialization;\nusing System.Text.RegularExpressions;\nusing GameDevWare.Serialization.Metadata;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic class ObjectSerializer : TypeSerializer\n\t{\n\t\tpublic const string TYPE_MEMBER_NAME = \"_type\";\n\n\t\tprivate static readonly Regex VersionRegEx = new Regex(@\", Version=[^\\]]+\", RegexOptions.None);\n\t\tprivate static readonly string BclTypePart = typeof(byte).AssemblyQualifiedName.Substring(typeof(byte).FullName.Length);\n\n\t\tprivate readonly Type objectType;\n\t\tprivate readonly string objectTypeNameWithoutVersion;\n\t\tprivate readonly TypeDescription objectTypeDescription;\n\t\tprivate readonly ObjectSerializer baseTypeSerializer;\n\t\tprivate readonly SerializationContext context;\n\n\t\tpublic override Type SerializedType { get { return this.objectType; } }\n\n\t\tpublic bool SuppressTypeInformation { get; set; }\n\n\t\tpublic ObjectSerializer(SerializationContext context, Type type)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\t\t\tif (context == null) throw new ArgumentNullException(\"context\");\n\n\t\t\tthis.context = context;\n\t\t\tthis.objectType = type;\n\t\t\tthis.objectTypeNameWithoutVersion = GetVersionInvariantObjectTypeName(this.objectType);\n\t\t\tthis.SuppressTypeInformation = (context.Options & SerializationOptions.SuppressTypeInformation) ==\n\t\t\t\t\t\t\t\t\t\t   SerializationOptions.SuppressTypeInformation;\n\n\t\t\tif (this.objectType.BaseType != null && this.objectType.BaseType != typeof(object))\n\t\t\t{\n\t\t\t\tvar baseSerializer = context.GetSerializerForType(this.objectType.BaseType);\n\t\t\t\tif (baseSerializer is ObjectSerializer == false)\n\t\t\t\t{\n\t\t\t\t\tthrow JsonSerializationException.TypeRequiresCustomSerializer(this.objectType, this.GetType());\n\t\t\t\t}\n\t\t\t\tthis.baseTypeSerializer = (ObjectSerializer)baseSerializer;\n\t\t\t}\n\n\t\t\tthis.objectTypeDescription = TypeDescription.Get(type);\n\t\t}\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token != JsonToken.BeginObject)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.BeginObject);\n\n\t\t\tvar serializerOverride = default(ObjectSerializer);\n\t\t\tvar container = new IndexedDictionary<string, object>(10);\n\t\t\treader.Context.Hierarchy.Push(container);\n\t\t\tvar instance = this.DeserializeMembers(reader, container, ref serializerOverride);\n\t\t\treader.Context.Hierarchy.Pop();\n\n\t\t\tif (reader.Token != JsonToken.EndOfObject)\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.EndOfObject);\n\n\t\t\tif (instance != null)\n\t\t\t\treturn instance;\n\t\t\telse if (serializerOverride != null)\n\t\t\t\treturn serializerOverride.PopulateInstance(container, null);\n\t\t\telse\n\t\t\t\treturn this.PopulateInstance(container, null);\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar container = new IndexedDictionary<DataMemberDescription, object>();\n\n\t\t\tthis.CollectMemberValues(value, container);\n\n\t\t\tif (this.SuppressTypeInformation || this.objectTypeDescription.IsAnonymousType)\n\t\t\t{\n\t\t\t\twriter.WriteObjectBegin(container.Count);\n\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.WriteObjectBegin(container.Count + 1);\n\n\t\t\t\twriter.Context.Path.Push(new PathSegment(TYPE_MEMBER_NAME));\n\t\t\t\twriter.WriteMember(TYPE_MEMBER_NAME);\n\t\t\t\twriter.WriteString(objectTypeNameWithoutVersion);\n\t\t\t\tthis.context.Path.Pop();\n\t\t\t}\n\n\t\t\tforeach (var kv in container)\n\t\t\t{\n\t\t\t\twriter.Context.Path.Push(new PathSegment(kv.Key.Name));\n\t\t\t\twriter.WriteMember(kv.Key.Name);\n\t\t\t\twriter.WriteValue(kv.Value, kv.Key.ValueType);\n\t\t\t\tthis.context.Path.Pop();\n\t\t\t}\n\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\n\t\tprivate void CollectMemberValues(object instance, IndexedDictionary<DataMemberDescription, object> container)\n\t\t{\n\t\t\tif (this.baseTypeSerializer != null)\n\t\t\t\tthis.baseTypeSerializer.CollectMemberValues(instance, container);\n\n\t\t\tforeach (var member in this.objectTypeDescription.Members)\n\t\t\t{\n\t\t\t\tvar baseMemberWithSameName = default(DataMemberDescription);\n\t\t\t\tif (this.baseTypeSerializer != null && this.baseTypeSerializer.TryGetMember(member.Name, out baseMemberWithSameName))\n\t\t\t\t\tcontainer.Remove(baseMemberWithSameName);\n\n\t\t\t\tvar value = member.GetValue(instance);\n\n\t\t\t\tcontainer[member] = value;\n\t\t\t}\n\t\t}\n\t\tprivate object DeserializeMembers(IJsonReader reader, IndexedDictionary<string, object> container, ref ObjectSerializer serializerOverride)\n\t\t{\n\t\t\twhile (reader.NextToken() && reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tif (reader.Token != JsonToken.Member)\n\t\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.Member);\n\n\t\t\t\tstring memberName = null;\n\t\t\t\tobject value = null;\n\n\t\t\t\tmemberName = reader.Value.AsString; // string\n\t\t\t\tif (string.Equals(memberName, TYPE_MEMBER_NAME) && this.SuppressTypeInformation == false)\n\t\t\t\t{\n\t\t\t\t\tthis.context.Path.Push(new PathSegment(TYPE_MEMBER_NAME));\n\t\t\t\t\treader.NextToken();\n\t\t\t\t\tvar typeName = reader.ReadString(false);\n\t\t\t\t\tvar type = default(Type);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = reader.Context.GetType(typeName, true, true);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception getTypeError)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new SerializationException(string.Format(\"Failed to resolve type '{0}' of value for '{1}' of '{2}' type.\\r\\n\" +\n\t\t\t\t\t\t\t\"More detailed information in inner exception.\", typeName, memberName, this.objectType.Name), getTypeError);\n\t\t\t\t\t}\n\t\t\t\t\tthis.context.Path.Pop();\n\n\t\t\t\t\tif (type == typeof(object))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.DeserializeMembers(reader, container, ref serializerOverride);\n\t\t\t\t\t\treturn new object();\n\t\t\t\t\t}\n\n\t\t\t\t\tvar serializer = reader.Context.GetSerializerForType(type);\n\t\t\t\t\tif (serializer is ObjectSerializer)\n\t\t\t\t\t{\n\t\t\t\t\t\tserializerOverride = (ObjectSerializer)serializer;\n\t\t\t\t\t\tserializerOverride.DeserializeMembers(reader, container, ref serializerOverride);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treader.NextToken(); // nextToken to next member\n\t\t\t\t\t\tserializerOverride = null;\n\t\t\t\t\t\treturn serializer.Deserialize(reader);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.context.Path.Push(new PathSegment(memberName));\n\n\t\t\t\tvar member = default(DataMemberDescription);\n\t\t\t\tvar valueType = typeof(object);\n\n\t\t\t\tif (this.TryGetMember(memberName, out member))\n\t\t\t\t\tvalueType = member.ValueType;\n\n\t\t\t\treader.NextToken();\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvalue = reader.ReadValue(valueType, false);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\tthrow new SerializationException(string.Format(\"Failed to read value for member '{0}' of '{1}' type.\\r\\nMore detailed information in inner exception.\", memberName, this.objectType.Name), e);\n\t\t\t\t}\n\n\t\t\t\tcontainer[memberName] = value;\n\n\t\t\t\tthis.context.Path.Pop();\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\tprivate object PopulateInstance(IndexedDictionary<string, object> container, object instance)\n\t\t{\n\t\t\tif (instance == null && objectType == typeof(object))\n\t\t\t\treturn container;\n\n\t\t\tif (instance == null)\n\t\t\t\tinstance = objectTypeDescription.CreateInstance();\n\n\t\t\tforeach (var member in this.objectTypeDescription.Members)\n\t\t\t{\n\t\t\t\tvar memberName = member.Name;\n\t\t\t\tvar memberType = member.ValueType;\n\t\t\t\tvar defaultValue = member.DefaultValue;\n\n\t\t\t\tif (defaultValue == null || container.ContainsKey(memberName))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (defaultValue.GetType() == memberType)\n\t\t\t\t\tcontainer[memberName] = defaultValue;\n\t\t\t\telse if (\"[]\".Equals(defaultValue) || \"{}\".Equals(defaultValue))\n\t\t\t\t\tcontainer[memberName] = memberType.IsArray\n\t\t\t\t\t\t? Array.CreateInstance(memberType.GetElementType(), 0)\n\t\t\t\t\t\t: Activator.CreateInstance(memberType);\n\t\t\t\telse if (defaultValue is string)\n\t\t\t\t\tcontainer[memberName] = Json.Deserialize(memberType, (string)defaultValue, context);\n\t\t\t\telse\n\t\t\t\t\tcontainer[memberName] = Convert.ChangeType(defaultValue, memberType, context.Format);\n\t\t\t}\n\n\n\t\t\tforeach (var kv in container)\n\t\t\t{\n\t\t\t\tvar memberName = kv.Key;\n\t\t\t\tvar value = kv.Value;\n\t\t\t\tvar member = default(DataMemberDescription);\n\n\t\t\t\tif (!this.TryGetMember(memberName, out member))\n\t\t\t\t\tcontinue;\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tmember.SetValue(instance, value);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\tthrow new SerializationException(string.Format(\"Failed to set member '{0}' to value '{1}' of type {2}.\\r\\n More detailed information in inner exception.\",\n\t\t\t\t\t\tmemberName, value, value != null ? value.GetType().FullName : \"<null>\"), e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.baseTypeSerializer != null)\n\t\t\t\tthis.baseTypeSerializer.PopulateInstance(container, instance);\n\n\t\t\treturn instance;\n\t\t}\n\t\tprivate bool TryGetMember(string memberName, out DataMemberDescription member)\n\t\t{\n\t\t\tif (memberName == null) throw new ArgumentNullException(\"memberName\");\n\n\t\t\tif (this.objectTypeDescription.TryGetMember(memberName, out member))\n\t\t\t\treturn true;\n\n\t\t\tif (this.baseTypeSerializer == null)\n\t\t\t\treturn false;\n\n\t\t\treturn this.baseTypeSerializer.TryGetMember(memberName, out member);\n\t\t}\n\n\t\tpublic static object CreateInstance(IndexedDictionary<string, object> values)\n\t\t{\n\t\t\tif (values == null) throw new ArgumentNullException(\"values\");\n\n\t\t\tvar instanceType = typeof(object);\n\t\t\tvar instanceTypeName = default(object);\n\t\t\tif (values.TryGetValue(TYPE_MEMBER_NAME, out instanceTypeName))\n\t\t\t{\n\t\t\t\tvalues.Remove(TYPE_MEMBER_NAME);\n\t\t\t\tinstanceType = Type.GetType((string)instanceTypeName, true);\n\t\t\t}\n\t\t\treturn CreateInstance(values, instanceType);\n\t\t}\n\t\tpublic static object CreateInstance(IndexedDictionary<string, object> values, Type instanceType)\n\t\t{\n\t\t\tif (instanceType == null) throw new ArgumentNullException(\"instanceType\");\n\t\t\tif (values == null) throw new ArgumentNullException(\"values\");\n\n\t\t\tvar context = new SerializationContext();\n\t\t\tvar serializer = new ObjectSerializer(context, instanceType);\n\t\t\treturn serializer.PopulateInstance(values, null);\n\t\t}\n\t\tpublic static string GetVersionInvariantObjectTypeName(Type type)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\n\t\t\tvar fullName = (type.AssemblyQualifiedName ?? type.FullName ?? type.Name);\n\t\t\tfullName = VersionRegEx.Replace(fullName, string.Empty);\n\t\t\tfullName = fullName.Replace(BclTypePart, \"\"); // remove BCL path of type information for better interop compatibility\n\t\t\treturn fullName;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"object, {0}\", this.objectType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/ObjectSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: e6ed81f3cf274c95af11e943c5a64203\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/PrimitiveTypeSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class PrimitiveSerializer : TypeSerializer\n\t{\n\t\tprivate readonly Type primitiveType;\n\t\tprivate readonly TypeCode primitiveTypeCode;\n\n\t\tpublic override Type SerializedType { get { return this.primitiveType; } }\n\n\t\tpublic PrimitiveSerializer(Type primitiveType)\n\t\t{\n\t\t\tif (primitiveType == null) throw new ArgumentNullException(\"primitiveType\");\n\n\t\t\tif (primitiveType.IsGenericType && primitiveType.GetGenericTypeDefinition() == typeof(Nullable<>))\n\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(typeof(PrimitiveSerializer), \"can't be nullable type\");\n\n\t\t\tthis.primitiveType = primitiveType;\n\t\t\tthis.primitiveTypeCode = Type.GetTypeCode(primitiveType);\n\n\t\t\tif (this.primitiveTypeCode == TypeCode.Object || this.primitiveTypeCode == TypeCode.Empty ||\n\t\t\t\tthis.primitiveTypeCode == TypeCode.DBNull)\n\t\t\t\tthrow JsonSerializationException.TypeIsNotValid(this.GetType(), \"be a primitive type\");\n\t\t}\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t{\n\t\t\t\tif (this.primitiveTypeCode == TypeCode.String)\n\t\t\t\t\treturn null;\n\n\t\t\t\tthrow JsonSerializationException.UnexpectedToken(reader, JsonToken.Boolean, JsonToken.DateTime, JsonToken.Null, JsonToken.Number, JsonToken.StringLiteral);\n\t\t\t}\n\n\t\t\tvar value = default(object);\n\t\t\tswitch (primitiveTypeCode)\n\t\t\t{\n\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\tvalue = reader.ReadBoolean(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\tvalue = reader.ReadByte(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.DateTime:\n\t\t\t\t\tvalue = reader.ReadDateTime(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\tvalue = reader.ReadDecimal(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\tvalue = reader.ReadDouble(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\tvalue = reader.ReadInt16(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\tvalue = reader.ReadInt32(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\tvalue = reader.ReadInt64(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\tvalue = reader.ReadSByte(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\tvalue = reader.ReadSingle(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\tvalue = reader.ReadUInt16(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\tvalue = reader.ReadUInt32(false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\tvalue = reader.ReadUInt64(false);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvar valueStr = reader.ReadString(false);\n\t\t\t\t\tvalue = Convert.ChangeType(valueStr, this.primitiveType, reader.Context.Format);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tswitch (primitiveTypeCode)\n\t\t\t{\n\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\twriter.WriteBoolean((bool)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\twriter.WriteNumber((byte)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.DateTime:\n\t\t\t\t\twriter.WriteDateTime((DateTime)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\twriter.WriteNumber((decimal)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\twriter.WriteNumber((double)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\twriter.WriteNumber((short)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\twriter.WriteNumber((int)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\twriter.WriteNumber((long)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\twriter.WriteNumber((sbyte)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\twriter.WriteNumber((float)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\twriter.WriteNumber((ushort)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\twriter.WriteNumber((uint)value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\twriter.WriteNumber((ulong)value);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvar valueStr = default(string);\n\n\t\t\t\t\tif (value is IFormattable)\n\t\t\t\t\t\tvalueStr = (string)Convert.ChangeType(value, typeof(string), writer.Context.Format);\n\t\t\t\t\telse\n\t\t\t\t\t\tvalueStr = value.ToString();\n\n\t\t\t\t\twriter.WriteString(valueStr);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/PrimitiveTypeSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 859ced78d4a94d14b7d47a0e6e1b6ced\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/QuaternionSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class QuaternionSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Quaternion); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Quaternion();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tif (memberName == \"x\")\n\t\t\t\t\tvalue.x = reader.ReadSingle();\n\t\t\t\telse if (memberName == \"y\")\n\t\t\t\t\tvalue.y = reader.ReadSingle();\n\t\t\t\telse if (memberName == \"z\")\n\t\t\t\t\tvalue.z = reader.ReadSingle();\n\t\t\t\telse if (memberName == \"w\")\n\t\t\t\t\tvalue.w = reader.ReadSingle();\n\t\t\t\telse\n\t\t\t\t\treader.ReadValue(typeof(object));\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar quaternion = (Quaternion)value;\n\t\t\twriter.WriteObjectBegin(4);\n\t\t\twriter.WriteMember(\"x\");\n\t\t\twriter.Write(quaternion.x);\n\t\t\twriter.WriteMember(\"y\");\n\t\t\twriter.Write(quaternion.y);\n\t\t\twriter.WriteMember(\"z\");\n\t\t\twriter.Write(quaternion.z);\n\t\t\twriter.WriteMember(\"w\");\n\t\t\twriter.Write(quaternion.w);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/QuaternionSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 7a244cc0ddaf41539286e6dca2cfd601\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/RectSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class RectSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Rect); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Rect();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tif (memberName == \"x\")\n\t\t\t\t\tvalue.x = reader.ReadSingle();\n\t\t\t\telse if (memberName == \"y\")\n\t\t\t\t\tvalue.y = reader.ReadSingle();\n\t\t\t\telse if (memberName == \"width\")\n\t\t\t\t\tvalue.width = reader.ReadSingle();\n\t\t\t\telse if (memberName == \"height\")\n\t\t\t\t\tvalue.height = reader.ReadSingle();\n\t\t\t\telse\n\t\t\t\t\treader.ReadValue(typeof(object));\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar vector4 = (Rect)value;\n\t\t\twriter.WriteObjectBegin(4);\n\t\t\twriter.WriteMember(\"x\");\n\t\t\twriter.Write(vector4.x);\n\t\t\twriter.WriteMember(\"y\");\n\t\t\twriter.Write(vector4.y);\n\t\t\twriter.WriteMember(\"width\");\n\t\t\twriter.Write(vector4.width);\n\t\t\twriter.WriteMember(\"height\");\n\t\t\twriter.Write(vector4.height);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/RectSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: e9596b5ac9c642cca7b4e9efac805b19\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/StreamSerializer.cs",
    "content": "﻿/*\n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND\n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE\n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,\n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE\n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\n\tThis source code is distributed via Unity Asset Store,\n\tto use it in your project you should accept Terms of Service and EULA\n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\nusing System.IO;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class StreamSerializer : TypeSerializer\n\t{\n\t\tpublic static readonly StreamSerializer Instance = new StreamSerializer();\n\n\t\tpublic override Type SerializedType { get { return typeof(Stream); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tif (reader.RawValue is Stream)\n\t\t\t\treturn reader.RawValue;\n\t\t\telse if(reader.RawValue is byte[])\n\t\t\t\treturn new MemoryStream((byte[])reader.RawValue);\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar base64Str = Convert.ToString(reader.RawValue, reader.Context.Format);\n\t\t\t\tvar bytes = Convert.FromBase64String(base64Str);\n\t\t\t\treturn new MemoryStream(bytes);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar stream = value as Stream;\n\t\t\tif (value != null && stream == null) throw JsonSerializationException.TypeIsNotValid(this.GetType(), \"be a Stream\");\n\t\t\tif (!stream.CanRead) throw new JsonSerializationException(\"Stream couldn't be readed.\", JsonSerializationException.ErrorCode.StreamIsNotReadable);\n\n\t\t\tif (stream.CanSeek)\n\t\t\t{\n\t\t\t\tvar position = stream.Position;\n\t\t\t\tvar buffer = new byte[stream.Length - stream.Position];\n\t\t\t\tstream.Read(buffer, 0, buffer.Length);\n\t\t\t\tBinarySerializer.Instance.Serialize(writer, buffer);\n\t\t\t\tstream.Position = position;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar tmpStream = new MemoryStream();\n\t\t\t\tvar buffer = new byte[ushort.MaxValue];\n\t\t\t\tvar readed = 0;\n\n\t\t\t\twhile ((readed = stream.Read(buffer, 0, buffer.Length)) > 0)\n\t\t\t\t\ttmpStream.Write(buffer, 0, readed);\n\n\t\t\t\tBinarySerializer.Instance.Serialize(writer, tmpStream.ToArray());\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"stream\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/StreamSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 3de90ee415c945b683bc759458d38fb1\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/TimeSpanSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class TimeSpanSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(TimeSpan); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Number)\n\t\t\t\treturn new TimeSpan(reader.Value.AsInt64);\n\n\t\t\tvar timeSpanStr = reader.ReadString(false);\n\t\t\tvar value = TimeSpan.Parse(timeSpanStr);\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar timeSpan = (TimeSpan)value;\n\t\t\twriter.Write((long)timeSpan.Ticks);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/TimeSpanSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 7a6c1dec78094360871fca0d28f291e5\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/UriSerializer.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class UriSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Uri); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tvar uriStr = reader.ReadString(false);\n\t\t\tvar value = new Uri(uriStr);\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar uri = (Uri)value;\n\t\t\twriter.WriteString(uri.OriginalString);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/UriSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 295ef6663ceb4552a3dd3c6c265cef7c\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Vector2Serializer.cs",
    "content": "/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class Vector2Serializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Vector2); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Vector2();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tswitch (memberName)\n\t\t\t\t{\n\t\t\t\t\tcase \"x\": value.x = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"y\": value.y = reader.ReadSingle(); break;\n\t\t\t\t\tdefault: reader.ReadValue(typeof(object)); break;\n\t\t\t\t}\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar vector2 = (Vector2)value;\n\t\t\twriter.WriteObjectBegin(2);\n\t\t\twriter.WriteMember(\"x\");\n\t\t\twriter.Write(vector2.x);\n\t\t\twriter.WriteMember(\"y\");\n\t\t\twriter.Write(vector2.y);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Vector2Serializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 367d804563384832bf9db1d72a34d639\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Vector3Serializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class Vector3Serializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Vector3); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Vector3();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tswitch (memberName)\n\t\t\t\t{\n\t\t\t\t\tcase \"x\": value.x = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"y\": value.y = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"z\": value.z = reader.ReadSingle(); break;\n\t\t\t\t\tdefault: reader.ReadValue(typeof(object)); break;\n\t\t\t\t}\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar vector3 = (Vector3)value;\n\t\t\twriter.WriteObjectBegin(3);\n\t\t\twriter.WriteMember(\"x\");\n\t\t\twriter.Write(vector3.x);\n\t\t\twriter.WriteMember(\"y\");\n\t\t\twriter.Write(vector3.y);\n\t\t\twriter.WriteMember(\"z\");\n\t\t\twriter.Write(vector3.z);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Vector3Serializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: fb0cf45e7412469d816f2913f40b0040\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Vector4Serializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n#if UNITY_5 || UNITY_4 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_5_3_OR_NEWER\nusing System;\nusing UnityEngine;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class Vector4Serializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Vector4); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tif (reader.Token == JsonToken.Null)\n\t\t\t\treturn null;\n\n\t\t\tvar value = new Vector4();\n\t\t\treader.ReadObjectBegin();\n\t\t\twhile (reader.Token != JsonToken.EndOfObject)\n\t\t\t{\n\t\t\t\tvar memberName = reader.ReadMember();\n\t\t\t\tswitch (memberName)\n\t\t\t\t{\n\t\t\t\t\tcase \"x\": value.x = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"y\": value.y = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"z\": value.z = reader.ReadSingle(); break;\n\t\t\t\t\tcase \"w\": value.w = reader.ReadSingle(); break;\n\t\t\t\t\tdefault: reader.ReadValue(typeof(object)); break;\n\t\t\t\t}\n\t\t\t}\n\t\t\treader.ReadObjectEnd(nextToken: false);\n\t\t\treturn value;\n\t\t}\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar vector4 = (Vector4)value;\n\t\t\twriter.WriteObjectBegin(4);\n\t\t\twriter.WriteMember(\"x\");\n\t\t\twriter.Write(vector4.x);\n\t\t\twriter.WriteMember(\"y\");\n\t\t\twriter.Write(vector4.y);\n\t\t\twriter.WriteMember(\"z\");\n\t\t\twriter.Write(vector4.z);\n\t\t\twriter.WriteMember(\"w\");\n\t\t\twriter.Write(vector4.w);\n\t\t\twriter.WriteObjectEnd();\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/Vector4Serializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: a7eb2e329a0943fdb69b1bd0c4702574\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/VersionSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization.Serializers\n{\n\tpublic sealed class VersionSerializer : TypeSerializer\n\t{\n\t\tpublic override Type SerializedType { get { return typeof(Version); } }\n\n\t\tpublic override object Deserialize(IJsonReader reader)\n\t\t{\n\t\t\tif (reader == null) throw new ArgumentNullException(\"reader\");\n\n\t\t\tvar versionStr = reader.ReadString(false);\n\t\t\tvar value = new Version(versionStr);\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic override void Serialize(IJsonWriter writer, object value)\n\t\t{\n\t\t\tif (writer == null) throw new ArgumentNullException(\"writer\");\n\t\t\tif (value == null) throw new ArgumentNullException(\"value\");\n\n\t\t\tvar version = (Version)value;\n\t\t\twriter.WriteString(version.ToString());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers/VersionSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: e7871724320e4be09e241532835a6270\ntimeCreated: 1653295313"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/Serializers.meta",
    "content": "﻿fileFormatVersion: 2\nguid: acca4413426e43b8874cab39d0c52faa\nfolderAsset: yes\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/TypeSerializer.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\tpublic abstract class TypeSerializer\n\t{\n\t\tpublic abstract Type SerializedType { get; }\n\n\t\tpublic abstract object Deserialize(IJsonReader reader);\n\t\tpublic abstract void Serialize(IJsonWriter writer, object value);\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/TypeSerializer.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 44d201fe0e97475982f385f0edf98954\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/TypeSerializerAttribute.cs",
    "content": "﻿/* \n\tCopyright (c) 2019 Denis Zykov, GameDevWare.com\n\n\tThis a part of \"Json & MessagePack Serialization\" Unity Asset - https://www.assetstore.unity3d.com/#!/content/59918\n\n\tTHIS SOFTWARE IS DISTRIBUTED \"AS-IS\" WITHOUT ANY WARRANTIES, CONDITIONS AND \n\tREPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE \n\tIMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY, \n\tFITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE \n\tAND THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.\n\t\n\tThis source code is distributed via Unity Asset Store, \n\tto use it in your project you should accept Terms of Service and EULA \n\thttps://unity3d.com/ru/legal/as_terms\n*/\n\nusing System;\n\n// ReSharper disable once CheckNamespace\nnamespace GameDevWare.Serialization\n{\n\t[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]\n\tpublic class TypeSerializerAttribute : Attribute\n\t{\n\t\tpublic Type SerializerType { get; private set; }\n\n\t\tpublic TypeSerializerAttribute(Type type)\n\t\t{\n\t\t\tif (type == null) throw new ArgumentNullException(\"type\");\n\t\t\tif (typeof(TypeSerializer).IsAssignableFrom(type) == false) throw new ArgumentException(string.Format(\"Type '{0}' should inherit from '{1}'.\", type, typeof(TypeSerializer)), \"type\");\n\n\t\t\tthis.SerializerType = type;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization/TypeSerializerAttribute.cs.meta",
    "content": "﻿fileFormatVersion: 2\nguid: 978e180ab92d4831991cf25c4dde873f\ntimeCreated: 1653295312"
  },
  {
    "path": "Assets/Colyseus/Runtime/GameDevWare.Serialization.meta",
    "content": "fileFormatVersion: 2\nguid: ed2bae19aaafee64ca1ec0da9bc0202d\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime/WebSocket.meta",
    "content": "fileFormatVersion: 2\nguid: 8ad79c09e65aa9d448fed15c550df644\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Runtime.meta",
    "content": "fileFormatVersion: 2\nguid: 4c3110b6bc1ac284fb6c48a5420133a9\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Tests/.gitkeep",
    "content": ""
  },
  {
    "path": "Assets/Colyseus/Tests/Colyseus.Editor.Tests.asmdef",
    "content": "{\n    \"name\": \"Colyseus.Editor.Tests\",\n    \"references\": [\n        \"ColyseusSDK\"\n    ],\n    \"includePlatforms\": [\n        \"Editor\"\n    ],\n    \"excludePlatforms\": [],\n    \"allowUnsafeCode\": false,\n    \"overrideReferences\": false,\n    \"precompiledReferences\": [],\n    \"autoReferenced\": true,\n    \"defineConstraints\": [],\n    \"versionDefines\": [],\n    \"noEngineReferences\": false\n}\n"
  },
  {
    "path": "Assets/Colyseus/Tests/Colyseus.Editor.Tests.asmdef.meta",
    "content": "fileFormatVersion: 2\nguid: 81cbeb15a98104ba0883bf60f5cd26be\nAssemblyDefinitionImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Tests/Editor/ColyseusTests.meta",
    "content": "fileFormatVersion: 2\nguid: 66dd0dda83b239249a2d3553751e9854\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Tests/Editor/ServerSettingsEditor.cs",
    "content": "using System;\nusing Colyseus;\nusing UnityEngine;\nusing UnityEditor;\nusing System.IO;\n\n[CustomEditor(typeof(Settings))]\npublic class ServerSettingsEditor : Editor\n{\n    private SerializedProperty url;\n    private SerializedProperty port;\n    private SerializedProperty secureProto;\n    private SerializedProperty requestHeaders;\n    bool serverInfoExpanded = false;\n\n    //private Texture colyseusIcon;\n    private float buttonWidth = 250;\n    private float sectionSpacer = 20;\n\n    void OnEnable()\n    {\n        url = serializedObject.FindProperty(\"colyseusServerAddress\");\n        port = serializedObject.FindProperty(\"colyseusServerPort\");\n        secureProto= serializedObject.FindProperty(\"useSecureProtocol\");\n        requestHeaders = serializedObject.FindProperty(\"_requestHeaders\");\n\n        //\n        // TODO: Why loading icon never works?\n\t\t// I've spent more than 2 hours here!\n        //\n        //colyseusIcon = EditorGUIUtility.IconContent(\"ColyseusSettings\").image;\n    }\n\n    public override void OnInspectorGUI()\n    {\n        serializedObject.Update();\n\n        EditorGUILayout.LabelField(\"Colyseus Server Settings\", EditorStyles.boldLabel);\n        serverInfoExpanded = EditorGUILayout.Foldout(serverInfoExpanded, \"Server Information\");\n        if (serverInfoExpanded)\n        {\n            EditorGUILayout.PropertyField(url);\n            EditorGUILayout.PropertyField(port);\n            EditorGUILayout.PropertyField(secureProto);\n        }\n\n        EditorGUILayout.PropertyField(requestHeaders);\n\n        EditorGUILayout.Space(sectionSpacer);\n        EditorGUILayout.LabelField(\"Additional Resources\", EditorStyles.boldLabel);\n        //if (GUILayout.Button(\"Colyseus Cloud Dashboard\", GUILayout.MaxWidth(buttonWidth)))\n        //{\n        //    Application.OpenURL(\"https://cloud.colyseus.io/\");\n        //}\n        if (GUILayout.Button(\"Documentation\", GUILayout.MaxWidth(buttonWidth)))\n        {\n            Application.OpenURL(\"https://docs.colyseus.io/?utm_source=unity-editor\");\n        }\n        serializedObject.ApplyModifiedProperties();\n    }\n}\n"
  },
  {
    "path": "Assets/Colyseus/Tests/Editor/ServerSettingsEditor.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 555b5346159acaa44a7bf91b37d18bb6\nMonoImporter:\n  externalObjects: {}\n  serializedVersion: 2\n  defaultReferences: []\n  executionOrder: 0\n  icon: {instanceID: 0}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Tests/Editor.meta",
    "content": "fileFormatVersion: 2\nguid: 4540f545322b50340b34ee357b3ea0bc\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Tests/Runtime/.gitkeep",
    "content": ""
  },
  {
    "path": "Assets/Colyseus/Tests/Runtime.meta",
    "content": "fileFormatVersion: 2\nguid: e93087128c596c843a6b8d2349538646\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/Tests.meta",
    "content": "fileFormatVersion: 2\nguid: c1c27865c8ba44b419c499d6fa54b4c5\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus/package.json",
    "content": "{\n\t\"name\": \"io.colyseus.sdk\",\n\t\"version\": \"0.17.16\",\n\t\"displayName\": \"Colyseus SDK\",\n\t\"description\": \"Colyseus Multiplayer SDK for Unity\",\n\t\"unity\": \"2019.1\",\n\t\"license\": \"MIT\",\n\t\"category\": \"Networking\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/colyseus/colyseus-unity-sdk.git\"\n\t},\n\t\"author\": {\n\t\t\"name\": \"Endel Dreyer\",\n\t\t\"email\": \"endel@colyseus.io\",\n\t\t\"url\": \"https://colyseus.io/\"\n\t},\n\t\"keywords\": [\n\t\t\"colyseus\",\n\t\t\"multiplayer\",\n\t\t\"networking\",\n\t\t\"authoritative\",\n\t\t\"netcode\"\n\t],\n\t\"dependencies\": {},\n\t\"samples\": [\n\t\t{\n\t\t\t\"displayName\": \"Example\",\n\t\t\t\"description\": \"Barebones usage example, demonstrating how to join custom rooms, send messages, and receive state updates. Includes LobbyRoom and QueueRoom examples.\",\n\t\t\t\"path\": \"Runtime/Example~\"\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "Assets/Colyseus/package.json.meta",
    "content": "fileFormatVersion: 2\nguid: e0d64eda35ff7e4408b1587a8edcaa3e\nPackageManifestImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "Assets/Colyseus.meta",
    "content": "fileFormatVersion: 2\nguid: 839fe1dd786fb7a4caaee63ba1a9df72\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# Bumping the package version\n\n- When asked to update version, bump semver patch version at ./Assets/Colyseus/package.json "
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2015-2016 Endel Dreyer\n\nMIT License:\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "Packages/manifest.json",
    "content": "{\n  \"dependencies\": {\n    \"com.unity.2d.sprite\": \"1.0.0\",\n    \"com.unity.ai.navigation\": \"2.0.9\",\n    \"com.unity.collab-proxy\": \"2.9.3\",\n    \"com.unity.ide.rider\": \"3.0.37\",\n    \"com.unity.ide.visualstudio\": \"2.0.25\",\n    \"com.unity.multiplayer.center\": \"1.0.0\",\n    \"com.unity.multiplayer.playmode\": \"1.6.0\",\n    \"com.unity.timeline\": \"1.8.9\",\n    \"com.unity.ugui\": \"2.0.0\",\n    \"com.unity.modules.accessibility\": \"1.0.0\",\n    \"com.unity.modules.ai\": \"1.0.0\",\n    \"com.unity.modules.androidjni\": \"1.0.0\",\n    \"com.unity.modules.animation\": \"1.0.0\",\n    \"com.unity.modules.assetbundle\": \"1.0.0\",\n    \"com.unity.modules.audio\": \"1.0.0\",\n    \"com.unity.modules.cloth\": \"1.0.0\",\n    \"com.unity.modules.director\": \"1.0.0\",\n    \"com.unity.modules.imageconversion\": \"1.0.0\",\n    \"com.unity.modules.imgui\": \"1.0.0\",\n    \"com.unity.modules.jsonserialize\": \"1.0.0\",\n    \"com.unity.modules.particlesystem\": \"1.0.0\",\n    \"com.unity.modules.physics\": \"1.0.0\",\n    \"com.unity.modules.physics2d\": \"1.0.0\",\n    \"com.unity.modules.screencapture\": \"1.0.0\",\n    \"com.unity.modules.terrain\": \"1.0.0\",\n    \"com.unity.modules.terrainphysics\": \"1.0.0\",\n    \"com.unity.modules.tilemap\": \"1.0.0\",\n    \"com.unity.modules.ui\": \"1.0.0\",\n    \"com.unity.modules.uielements\": \"1.0.0\",\n    \"com.unity.modules.umbra\": \"1.0.0\",\n    \"com.unity.modules.unityanalytics\": \"1.0.0\",\n    \"com.unity.modules.unitywebrequest\": \"1.0.0\",\n    \"com.unity.modules.unitywebrequestassetbundle\": \"1.0.0\",\n    \"com.unity.modules.unitywebrequestaudio\": \"1.0.0\",\n    \"com.unity.modules.unitywebrequesttexture\": \"1.0.0\",\n    \"com.unity.modules.unitywebrequestwww\": \"1.0.0\",\n    \"com.unity.modules.vehicles\": \"1.0.0\",\n    \"com.unity.modules.video\": \"1.0.0\",\n    \"com.unity.modules.vr\": \"1.0.0\",\n    \"com.unity.modules.wind\": \"1.0.0\",\n    \"com.unity.modules.xr\": \"1.0.0\"\n  }\n}\n"
  },
  {
    "path": "Packages/packages-lock.json",
    "content": "{\n  \"dependencies\": {\n    \"com.unity.2d.sprite\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.ai.navigation\": {\n      \"version\": \"2.0.9\",\n      \"depth\": 0,\n      \"source\": \"registry\",\n      \"dependencies\": {\n        \"com.unity.modules.ai\": \"1.0.0\"\n      },\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.collab-proxy\": {\n      \"version\": \"2.9.3\",\n      \"depth\": 0,\n      \"source\": \"registry\",\n      \"dependencies\": {},\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.ext.nunit\": {\n      \"version\": \"2.0.5\",\n      \"depth\": 1,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.ide.rider\": {\n      \"version\": \"3.0.37\",\n      \"depth\": 0,\n      \"source\": \"registry\",\n      \"dependencies\": {\n        \"com.unity.ext.nunit\": \"1.0.6\"\n      },\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.ide.visualstudio\": {\n      \"version\": \"2.0.25\",\n      \"depth\": 0,\n      \"source\": \"registry\",\n      \"dependencies\": {\n        \"com.unity.test-framework\": \"1.1.31\"\n      },\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.multiplayer.center\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.uielements\": \"1.0.0\"\n      }\n    },\n    \"com.unity.multiplayer.playmode\": {\n      \"version\": \"1.6.0\",\n      \"depth\": 0,\n      \"source\": \"registry\",\n      \"dependencies\": {\n        \"com.unity.nuget.newtonsoft-json\": \"2.0.2\"\n      },\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.nuget.newtonsoft-json\": {\n      \"version\": \"3.2.1\",\n      \"depth\": 1,\n      \"source\": \"registry\",\n      \"dependencies\": {},\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.test-framework\": {\n      \"version\": \"1.5.1\",\n      \"depth\": 1,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.ext.nunit\": \"2.0.3\",\n        \"com.unity.modules.imgui\": \"1.0.0\",\n        \"com.unity.modules.jsonserialize\": \"1.0.0\"\n      }\n    },\n    \"com.unity.timeline\": {\n      \"version\": \"1.8.9\",\n      \"depth\": 0,\n      \"source\": \"registry\",\n      \"dependencies\": {\n        \"com.unity.modules.audio\": \"1.0.0\",\n        \"com.unity.modules.director\": \"1.0.0\",\n        \"com.unity.modules.animation\": \"1.0.0\",\n        \"com.unity.modules.particlesystem\": \"1.0.0\"\n      },\n      \"url\": \"https://packages.unity.com\"\n    },\n    \"com.unity.ugui\": {\n      \"version\": \"2.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.ui\": \"1.0.0\",\n        \"com.unity.modules.imgui\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.accessibility\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.ai\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.androidjni\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.animation\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.assetbundle\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.audio\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.cloth\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.physics\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.director\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.audio\": \"1.0.0\",\n        \"com.unity.modules.animation\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.hierarchycore\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 1,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.imageconversion\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.imgui\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.jsonserialize\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.particlesystem\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.physics\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.physics2d\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.screencapture\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.imageconversion\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.subsystems\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 1,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.jsonserialize\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.terrain\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.terrainphysics\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.physics\": \"1.0.0\",\n        \"com.unity.modules.terrain\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.tilemap\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.physics2d\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.ui\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.uielements\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.ui\": \"1.0.0\",\n        \"com.unity.modules.imgui\": \"1.0.0\",\n        \"com.unity.modules.jsonserialize\": \"1.0.0\",\n        \"com.unity.modules.hierarchycore\": \"1.0.0\",\n        \"com.unity.modules.physics\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.umbra\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.unityanalytics\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.unitywebrequest\": \"1.0.0\",\n        \"com.unity.modules.jsonserialize\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.unitywebrequest\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.unitywebrequestassetbundle\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.assetbundle\": \"1.0.0\",\n        \"com.unity.modules.unitywebrequest\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.unitywebrequestaudio\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.unitywebrequest\": \"1.0.0\",\n        \"com.unity.modules.audio\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.unitywebrequesttexture\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.unitywebrequest\": \"1.0.0\",\n        \"com.unity.modules.imageconversion\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.unitywebrequestwww\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.unitywebrequest\": \"1.0.0\",\n        \"com.unity.modules.unitywebrequestassetbundle\": \"1.0.0\",\n        \"com.unity.modules.unitywebrequestaudio\": \"1.0.0\",\n        \"com.unity.modules.audio\": \"1.0.0\",\n        \"com.unity.modules.assetbundle\": \"1.0.0\",\n        \"com.unity.modules.imageconversion\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.vehicles\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.physics\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.video\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.audio\": \"1.0.0\",\n        \"com.unity.modules.ui\": \"1.0.0\",\n        \"com.unity.modules.unitywebrequest\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.vr\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.jsonserialize\": \"1.0.0\",\n        \"com.unity.modules.physics\": \"1.0.0\",\n        \"com.unity.modules.xr\": \"1.0.0\"\n      }\n    },\n    \"com.unity.modules.wind\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {}\n    },\n    \"com.unity.modules.xr\": {\n      \"version\": \"1.0.0\",\n      \"depth\": 0,\n      \"source\": \"builtin\",\n      \"dependencies\": {\n        \"com.unity.modules.physics\": \"1.0.0\",\n        \"com.unity.modules.jsonserialize\": \"1.0.0\",\n        \"com.unity.modules.subsystems\": \"1.0.0\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "ProjectSettings/PackageManagerSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!114 &1\nMonoBehaviour:\n  m_ObjectHideFlags: 61\n  m_CorrespondingSourceObject: {fileID: 0}\n  m_PrefabInstance: {fileID: 0}\n  m_PrefabAsset: {fileID: 0}\n  m_GameObject: {fileID: 0}\n  m_Enabled: 1\n  m_EditorHideFlags: 0\n  m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}\n  m_Name: \n  m_EditorClassIdentifier: \n  m_EnablePreviewPackages: 0\n  m_EnablePackageDependencies: 0\n  m_AdvancedSettingsExpanded: 1\n  m_ScopedRegistriesSettingsExpanded: 1\n  oneTimeWarningShown: 0\n  m_Registries:\n  - m_Id: main\n    m_Name: \n    m_Url: https://packages.unity.com\n    m_Scopes: []\n    m_IsDefault: 1\n    m_Capabilities: 7\n  m_UserSelectedRegistryName: \n  m_UserAddingNewScopedRegistry: 0\n  m_RegistryInfoDraft:\n    m_ErrorMessage: \n    m_Original:\n      m_Id: \n      m_Name: \n      m_Url: \n      m_Scopes: []\n      m_IsDefault: 0\n      m_Capabilities: 0\n    m_Modified: 0\n    m_Name: \n    m_Url: \n    m_Scopes:\n    - \n    m_SelectedScopeIndex: 0\n"
  },
  {
    "path": "ProjectSettings/ProjectVersion.txt",
    "content": "m_EditorVersion: 6000.2.5f1\nm_EditorVersionWithRevision: 6000.2.5f1 (43d04cd1df69)\n"
  },
  {
    "path": "ProjectSettings/XRSettings.asset",
    "content": "{\n    \"m_SettingKeys\": [\n        \"VR Device Disabled\",\n        \"VR Device User Alert\"\n    ],\n    \"m_SettingValues\": [\n        \"False\",\n        \"False\"\n    ]\n}"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://github.com/colyseus/colyseus\">\n    <img src=\"https://github.com/colyseus/colyseus/blob/master/media/logo.svg?raw=true\" width=\"40%\" height=\"100\" />\n  </a>\n  <br>\n  <br>\n  <a href=\"https://npmjs.com/package/colyseus\">\n    <img src=\"https://img.shields.io/npm/dm/colyseus.svg?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAHdElNRQfjAgETESWYxR33AAAAtElEQVQoz4WQMQrCQBRE38Z0QoTcwF4Qg1h4BO0sxGOk80iCtViksrIQRRBTewWxMI1mbELYjYu+4rPMDPtn12ChMT3gavb4US5Jym0tcBIta3oDHv4Gwmr7nC4QAxBrCdzM2q6XqUnm9m9r59h7Rc0n2pFv24k4ttGMUXW+sGELTJjSr7QDKuqLS6UKFChVWWuFkZw9Z2AAvAirKT+JTlppIRnd6XgaP4goefI2Shj++OnjB3tBmHYK8z9zAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE5LTAyLTAxVDE4OjE3OjM3KzAxOjAwGQQixQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOS0wMi0wMVQxODoxNzozNyswMTowMGhZmnkAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC\">\n  </a>\n  <a href=\"https://forum.colyseus.io/\" title=\"Discuss on Forum\">\n    <img src=\"https://img.shields.io/badge/discuss-on%20forum-brightgreen.svg?style=for-the-badge&colorB=0069b8&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAHdElNRQfjAgETDROxCNUzAAABB0lEQVQoz4WRvyvEARjGP193CnWRH+dHQmGwKZtFGcSmxHAL400GN95ktIpV2dzlLzDJgsGgGNRdDAzoQueS/PgY3HXHyT3T+/Y87/s89UANBKXBdoZo5J6L4K1K5ZxHfnjnlQUf3bKvkgy57a0r9hS3cXfMO1kWJMza++tj3Ac7/LY343x1NA9cNmYMwnSS/SP8JVFuSJmr44iFqvtmpjhmhBCrOOazCesq6H4P3bPBjFoIBydOk2bUA17I080Es+wSZ51B4DIA2zgjSpYcEe44Js01G0XjRcCU+y4ZMrDeLmfc9EnVd5M/o0VMeu6nJZxWJivLmhyw1WHTvrr2b4+2OFqra+ALwouTMDcqmjMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDItMDFUMTg6MTM6MTkrMDE6MDAC9f6fAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTAyLTAxVDE4OjEzOjE5KzAxOjAwc6hGIwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=\" alt=\"Discussion forum\" />\n  </a>\n  <a href=\"https://discord.gg/RY8rRS7\">\n    <img src=\"https://img.shields.io/discord/525739117951320081.svg?style=for-the-badge&colorB=7581dc&logo=discord&logoColor=white\">\n  </a>\n  <h3>\n     Colyseus Multiplayer SDK for C# <br />For <a href=\"https://docs.colyseus.io/getting-started/unity\">Unity</a>, <a href=\"https://docs.colyseus.io/getting-started/monogame\">MonoGame</a>, Godot Mono, etc.<br />\n  </h3>\n</div>\n\n> **Note:** This README covers development and contributing to the SDK. For end-user installation and usage, see the [Documentation](https://docs.colyseus.io/) ([Unity](https://docs.colyseus.io/getting-started/unity) | [MonoGame](https://docs.colyseus.io/getting-started/monogame) | [Godot](https://docs.colyseus.io/getting-started/godot)).\n\n## Setup\n\n### Unity\n\nRun `unity-setup.sh` to fetch external dependencies (e.g. [NativeWebSocket](https://github.com/endel/NativeWebSocket)) into `Assets/Colyseus/Runtime/WebSocket/`:\n\n```\nbash unity-setup.sh\n```\n\nThis is required before opening the project in Unity. The fetched files are gitignored and bundled automatically during CI for UPM and `.unitypackage` releases.\n\n### NuGet / Godot / MonoGame\n\nExternal dependencies are resolved via NuGet packages — no setup script needed. The SDK is available as the `Colyseus` NuGet package, which depends on `Colyseus.NativeWebSocket`.\n\nWhen the client is created on an engine main thread with a `SynchronizationContext` (Unity, Godot C#), WebSocket callbacks are marshaled back there automatically. Engines without one can register an external dispatcher through `ColyseusContext.RegisterWebSocketForDispatch`, or call `room.Connection.DispatchMessageQueue()` from their update loop.\n\n## Running the test server\n\nIn order to start a test server for this project's included example, do the following:\n\n```\ngit clone https://github.com/colyseus/sdks-test-server\ncd sdks-test-server\nnpm install\nnpm start\n```\n\n## Running tests\n\n```\ndotnet test nuget/Colyseus.csproj\n```\n\n### Releasing a new version\n\nUpdate the version number under `Assets/Colyseus/package.json` and push to `master` branch.\n\n## License\n\nMIT\n"
  },
  {
    "path": "UserSettings/EditorUserSettings.asset",
    "content": "%YAML 1.1\n%TAG !u! tag:unity3d.com,2011:\n--- !u!162 &1\nEditorUserSettings:\n  m_ObjectHideFlags: 0\n  serializedVersion: 4\n  m_ConfigSettings:\n    RecentlyUsedSceneGuid-0:\n      value: 5009500407530c0a585f587645270844424e1a7e2f7825642c7f1931b2b93739\n      flags: 0\n    RecentlyUsedSceneGuid-1:\n      value: 5401555453530a035458097a44730b44474e1e2b2d787e65787d4a63e4b5623d\n      flags: 0\n    RecentlyUsedSceneGuid-2:\n      value: 0007555056545159085f087340770b48404e1b7d292e76347c284462e6e4316c\n      flags: 0\n    vcSharedLogLevel:\n      value: 0d5e400f0650\n      flags: 0\n  m_VCAutomaticAdd: 1\n  m_VCDebugCom: 0\n  m_VCDebugCmd: 0\n  m_VCDebugOut: 0\n  m_SemanticMergeMode: 2\n  m_DesiredImportWorkerCount: 2\n  m_StandbyImportWorkerCount: 2\n  m_IdleImportWorkerShutdownDelay: 60000\n  m_VCShowFailedCheckout: 1\n  m_VCOverwriteFailedCheckoutAssets: 1\n  m_VCProjectOverlayIcons: 1\n  m_VCHierarchyOverlayIcons: 1\n  m_VCOtherOverlayIcons: 1\n  m_VCAllowAsyncUpdate: 0\n  m_VCScanLocalPackagesOnConnect: 1\n  m_ArtifactGarbageCollection: 1\n  m_CompressAssetsOnImport: 1\n"
  },
  {
    "path": "nuget/Colyseus.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <!-- <TargetFrameworks>netstandard2.1;net8.0;net10.0</TargetFrameworks> -->\n    <TargetFrameworks>netstandard2.1;net8.0</TargetFrameworks>\n    <NoWarn>NU5128</NoWarn>\n    <LangVersion>9.0</LangVersion>\n    <AssemblyName>Colyseus</AssemblyName>\n    <RootNamespace>Colyseus</RootNamespace>\n    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>\n    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>\n    <IsTestProject Condition=\"'$(TargetFramework)' != 'netstandard2.1'\">true</IsTestProject>\n    <IsPackable>true</IsPackable>\n    <!-- Only ship the netstandard2.1 library in the NuGet package (net8.0 is for tests only) -->\n    <IncludeBuildOutput Condition=\"'$(TargetFramework)' == 'net8.0'\">false</IncludeBuildOutput>\n\n    <!-- NuGet package metadata (version is read from Assets/Colyseus/package.json) -->\n    <PackageId>Colyseus</PackageId>\n    <Authors>Endel Dreyer</Authors>\n    <Description>Colyseus Multiplayer SDK — engine-agnostic core (Schema serialization, matchmaking, rooms).</Description>\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\n    <PackageProjectUrl>https://colyseus.io/</PackageProjectUrl>\n    <RepositoryUrl>https://github.com/colyseus/colyseus-unity-sdk</RepositoryUrl>\n    <PackageTags>colyseus;multiplayer;networking;authoritative;netcode;gamedev</PackageTags>\n    <PackageReadmeFile>README.md</PackageReadmeFile>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <None Include=\"README.md\" Pack=\"true\" PackagePath=\"\\\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Colyseus.NativeWebSocket\" Version=\"2.0.0\" />\n  </ItemGroup>\n\n  <ItemGroup Condition=\"'$(TargetFramework)' != 'netstandard2.1'\">\n    <PackageReference Include=\"NUnit\" Version=\"3.14.0\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"NUnit3TestAdapter\" Version=\"4.6.0\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.12.0\" PrivateAssets=\"all\" />\n  </ItemGroup>\n\n  <!-- Core SDK files (engine-agnostic) -->\n  <ItemGroup>\n    <Compile Include=\"../Assets/Colyseus/Runtime/Colyseus/**/*.cs\"\n             Exclude=\"../Assets/Colyseus/Runtime/Colyseus/Unity/**/*.cs;../Assets/Colyseus/Runtime/Colyseus/Manager.cs;../Assets/Colyseus/Runtime/Colyseus/Utils/UnityWebRequestAwaiter.cs;../Assets/Colyseus/Runtime/Colyseus/Utils/ExtensionMethods.cs\" />\n    <Compile Include=\"../Assets/Colyseus/Runtime/GameDevWare.Serialization/**/*.cs\" />\n  </ItemGroup>\n\n  <!-- Test files (compile for testing, but exclude from NuGet package) -->\n  <ItemGroup Condition=\"'$(TargetFramework)' != 'netstandard2.1'\">\n    <Compile Include=\"tests/**/*.cs\" />\n  </ItemGroup>\n\n  <!-- Read version from UPM package.json -->\n  <Target Name=\"SetVersionFromPackageJson\" BeforeTargets=\"PrepareForBuild;GenerateNuspec\">\n    <Exec Command=\"python3 -c &quot;import json; print(json.load(open('$(MSBuildProjectDirectory)/../Assets/Colyseus/package.json'))['version'])&quot;\" ConsoleToMSBuild=\"true\">\n      <Output TaskParameter=\"ConsoleOutput\" PropertyName=\"PackageVersion\" />\n    </Exec>\n  </Target>\n\n</Project>\n"
  },
  {
    "path": "nuget/README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://colyseus.io/\">\n    <img src=\"https://github.com/colyseus/colyseus/blob/master/media/logo.svg?raw=true\" width=\"40%\" />\n  </a>\n  <h3>Colyseus Multiplayer SDK for C#/.NET</h3>\n</div>\n\nEngine-agnostic core SDK for [Colyseus](https://colyseus.io/) — includes Schema serialization, matchmaking, room management, and state synchronization.\n\nWorks with Unity, Godot (C#), MonoGame, and any .NET project.\n\n## Installation\n\n```sh\ndotnet add package Colyseus\n```\n\n## Threading\n\nWhen the client is created on a thread with a `SynchronizationContext` (Unity, Godot C#), Colyseus posts WebSocket callbacks back to that context automatically.\n\nFor engines without one, either register an external dispatcher through `ColyseusContext.RegisterWebSocketForDispatch`, or call `room.Connection.DispatchMessageQueue()` from your update loop.\n\n## Quick Example\n\n```csharp\nusing Colyseus;\nusing Colyseus.Schema;\n\nvar client = new Client(\"ws://localhost:2567\");\n\nvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\nConsole.WriteLine(\"Joined room: \" + room.Id);\n\nvar callbacks = Callbacks.Get(room);\n\ncallbacks.Listen(state => state.currentTurn, (currentValue, previousValue) => {\n    Console.WriteLine($\"Turn changed: {previousValue} -> {currentValue}\");\n});\n\ncallbacks.OnAdd(state => state.players, (sessionId, player) => {\n    Console.WriteLine($\"Player joined: {sessionId}\");\n});\n\nroom.Send(\"move\", new { x = 10f, y = 20f });\n\nroom.OnMessage<string>(\"chat\", (message) => {\n    Console.WriteLine(\"Chat: \" + message);\n});\n```\n\n## Documentation\n\nSee the full documentation at **https://docs.colyseus.io/getting-started/unity**\n\n## License\n\nMIT\n"
  },
  {
    "path": "nuget/tests/HTTPTest.cs",
    "content": "using NUnit.Framework;\n\nnamespace Colyseus.Tests\n{\n\n\t[TestFixture]\n\tpublic class HTTPTest\n\t{\n\n\t\t[Test]\n\t\tpublic void UnsecureRootPathWithPortTest()\n\t\t{\n\t\t\tvar settings = Colyseus.Settings.Create();\n\t\t\tsettings.colyseusServerAddress = \"localhost\";\n\t\t\tsettings.colyseusServerPort = \"2567\";\n\t\t\tsettings.useSecureProtocol = false;\n\n\t\t\tvar request = new Colyseus.HTTP(settings);\n\t\t\tAssert.AreEqual(\"http://localhost:2567/\", request.GetRequestURL(\"\").ToString());\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnsecureChildPathWithPortTest()\n\t\t{\n\t\t\tvar settings = Colyseus.Settings.Create();\n\t\t\tsettings.colyseusServerAddress = \"localhost/path\";\n\t\t\tsettings.colyseusServerPort = \"2567\";\n\t\t\tsettings.useSecureProtocol = false;\n\n\t\t\tvar request = new Colyseus.HTTP(settings);\n\t\t\tAssert.AreEqual(\"http://localhost:2567/path/\", request.GetRequestURL(\"\").ToString());\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnsecureChildPathNoPortTest()\n\t\t{\n\t\t\tvar settings = Colyseus.Settings.Create();\n\t\t\tsettings.colyseusServerAddress = \"localhost/path\";\n\t\t\tsettings.colyseusServerPort = \"80\";\n\t\t\tsettings.useSecureProtocol = false;\n\n\t\t\tvar request = new Colyseus.HTTP(settings);\n\t\t\tAssert.AreEqual(\"http://localhost/path/\", request.GetRequestURL(\"\").ToString());\n\t\t}\n\n\n\t\t[Test]\n\t\tpublic void SecureChildPathNoPortTest()\n\t\t{\n\t\t\tvar settings = Colyseus.Settings.Create();\n\t\t\tsettings.colyseusServerAddress = \"localhost/path\";\n\t\t\tsettings.colyseusServerPort = \"443\";\n\t\t\tsettings.useSecureProtocol = true;\n\n\t\t\tvar request = new Colyseus.HTTP(settings);\n\t\t\tAssert.AreEqual(\"https://localhost/path/\", request.GetRequestURL(\"\").ToString());\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SecureChildPathWithPortTest()\n\t\t{\n\t\t\tvar settings = Colyseus.Settings.Create();\n\t\t\tsettings.colyseusServerAddress = \"localhost\";\n\t\t\tsettings.colyseusServerPort = \"8080\";\n\t\t\tsettings.useSecureProtocol = true;\n\n\t\t\tvar request = new Colyseus.HTTP(settings);\n\t\t\tAssert.AreEqual(\"https://localhost:8080/\", request.GetRequestURL(\"\").ToString());\n\t\t}\n\n\t}\n\n}\n"
  },
  {
    "path": "nuget/tests/HTTPTest.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 44622709f20ef48128f6b944dac20dde"
  },
  {
    "path": "nuget/tests/IntegrationTest.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing NUnit.Framework;\nusing Colyseus;\nusing Colyseus.Schema;\n\nnamespace Colyseus.Tests\n{\n\t[TestFixture]\n\tpublic class IntegrationTest\n\t{\n\t\tprivate Client client;\n\n\t\t[SetUp]\n\t\tpublic void Init()\n\t\t{\n\t\t\tclient = new Client(\"ws://localhost:2567\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task JoinRoom()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\n\t\t\tAssert.IsNotNull(room);\n\t\t\tAssert.IsNotNull(room.RoomId);\n\t\t\tAssert.IsNotNull(room.SessionId);\n\t\t\tAssert.AreEqual(\"my_room\", room.Name);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ReceiveInitialState()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\n\t\t\tvar received = await WithTimeout(stateReceived.Task, 5000);\n\t\t\tAssert.IsTrue(received, \"Should receive initial state\");\n\n\t\t\tvar state = room.State;\n\t\t\tAssert.IsNotNull(state.players);\n\t\t\tAssert.IsTrue(state.players.Count >= 1, \"Should have at least 1 player (self)\");\n\t\t\tAssert.IsNotNull(state.players[room.SessionId], \"Player should exist with own sessionId\");\n\n\t\t\t// Player should have an initial item (sword)\n\t\t\tvar self = state.players[room.SessionId];\n\t\t\tAssert.AreEqual(1, self.items.Count);\n\t\t\tAssert.AreEqual(\"sword\", self.items[0].name);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SendAndReceiveMessage_Move()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\t// Send move message\n\t\t\tawait room.Send(\"move\", new { x = 100, y = 200 });\n\n\t\t\t// Wait for state update\n\t\t\tawait Task.Delay(200);\n\n\t\t\tvar self = room.State.players[room.SessionId];\n\t\t\tAssert.AreEqual(100f, self.x);\n\t\t\tAssert.AreEqual(200f, self.y);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SendAndReceiveMessage_AddItem()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tvar self = room.State.players[room.SessionId];\n\t\t\tvar initialCount = self.items.Count;\n\n\t\t\tawait room.Send(\"add_item\", new { name = \"shield\" });\n\t\t\tawait Task.Delay(200);\n\n\t\t\tAssert.AreEqual(initialCount + 1, self.items.Count);\n\t\t\tAssert.AreEqual(\"shield\", self.items[self.items.Count - 1].name);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SendAndReceiveMessage_RemoveItem()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tvar self = room.State.players[room.SessionId];\n\t\t\tvar initialCount = self.items.Count;\n\t\t\tAssert.IsTrue(initialCount > 0, \"Should have at least 1 item\");\n\n\t\t\tawait room.Send(\"remove_item\", new { });\n\t\t\tawait Task.Delay(200);\n\n\t\t\tAssert.AreEqual(initialCount - 1, self.items.Count);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SendAndReceiveMessage_AddBot()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tvar initialCount = room.State.players.Count;\n\n\t\t\tawait room.Send(\"add_bot\", new { });\n\t\t\tawait Task.Delay(200);\n\n\t\t\tAssert.AreEqual(initialCount + 1, room.State.players.Count);\n\n\t\t\t// Find the bot\n\t\t\tPlayer bot = null;\n\t\t\troom.State.players.ForEach((key, player) =>\n\t\t\t{\n\t\t\t\tif (player.isBot)\n\t\t\t\t\tbot = player;\n\t\t\t});\n\t\t\tAssert.IsNotNull(bot, \"Should have a bot player\");\n\t\t\tAssert.IsTrue(bot.isBot);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task HostAssignment()\n\t\t{\n\t\t\tvar room = await client.Create<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tAssert.IsNotNull(room.State.host, \"First player should be assigned as host\");\n\t\t\tAssert.AreEqual(room.SessionId, room.State.currentTurn, \"First player should have the current turn\");\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task BroadcastMessage_Weather()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar weatherReceived = new TaskCompletionSource<object>();\n\n\t\t\troom.OnMessage<object>(\"weather\", (message) =>\n\t\t\t{\n\t\t\t\tif (!weatherReceived.Task.IsCompleted)\n\t\t\t\t\tweatherReceived.TrySetResult(message);\n\t\t\t});\n\n\t\t\t// Server broadcasts weather every 4 seconds\n\t\t\tvar weather = await WithTimeout(weatherReceived.Task, 6000);\n\t\t\tAssert.IsNotNull(weather, \"Should receive weather broadcast\");\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MultipleClients_SeeEachOther()\n\t\t{\n\t\t\tvar client2 = new Client(\"ws://localhost:2567\");\n\n\t\t\tvar room1 = await client.Create<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived1 = new TaskCompletionSource<bool>();\n\n\t\t\troom1.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived1.Task.IsCompleted)\n\t\t\t\t\tstateReceived1.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived1.Task, 5000);\n\n\t\t\t// Second client joins the same room\n\t\t\tvar room2 = await client2.JoinById<MyRoomState>(room1.RoomId);\n\t\t\tawait Task.Delay(500);\n\n\t\t\t// Both clients should see both players\n\t\t\tAssert.AreEqual(2, room1.State.players.Count, \"Room1 should see 2 players\");\n\t\t\tAssert.AreEqual(2, room2.State.players.Count, \"Room2 should see 2 players\");\n\n\t\t\tAssert.IsNotNull(room1.State.players[room2.SessionId], \"Room1 should see Room2's player\");\n\t\t\tAssert.IsNotNull(room2.State.players[room1.SessionId], \"Room2 should see Room1's player\");\n\n\t\t\tawait room1.Leave();\n\t\t\tawait room2.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task OnLeave_ConsentedLeave()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar leaveCode = new TaskCompletionSource<int>();\n\n\t\t\troom.OnLeave += (code) =>\n\t\t\t{\n\t\t\t\tif (!leaveCode.Task.IsCompleted)\n\t\t\t\t\tleaveCode.TrySetResult(code);\n\t\t\t};\n\n\t\t\tawait room.Leave(consented: true);\n\n\t\t\tvar code = await WithTimeout(leaveCode.Task, 5000);\n\t\t\tAssert.IsTrue(code > 0, $\"Should receive a close code, got {code}\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Reconnection_DropAndReconnect()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\t// Send a move so we can verify state persists after reconnection\n\t\t\tawait room.Send(\"move\", new { x = 42, y = 84 });\n\t\t\tawait Task.Delay(200);\n\n\t\t\tvar dropReceived = new TaskCompletionSource<int>();\n\t\t\tvar reconnectReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnDrop += (code) =>\n\t\t\t{\n\t\t\t\tif (!dropReceived.Task.IsCompleted)\n\t\t\t\t\tdropReceived.TrySetResult(code);\n\t\t\t};\n\n\t\t\troom.OnReconnect += () =>\n\t\t\t{\n\t\t\t\tif (!reconnectReceived.Task.IsCompleted)\n\t\t\t\t\treconnectReceived.TrySetResult(true);\n\t\t\t};\n\n\t\t\t// Disable min uptime check so reconnection triggers immediately\n\t\t\troom.Reconnection.MinUptime = 0;\n\n\t\t\t// Force-drop the connection\n\t\t\troom.Connection.Drop();\n\n\t\t\tvar dropCode = await WithTimeout(dropReceived.Task, 5000);\n\t\t\tAssert.IsTrue(\n\t\t\t\tdropCode == (int)CloseCode.ABNORMAL_CLOSURE ||\n\t\t\t\tdropCode == (int)CloseCode.NO_STATUS_RECEIVED ||\n\t\t\t\tdropCode == (int)CloseCode.GOING_AWAY,\n\t\t\t\t$\"Expected a reconnectable close code, got {dropCode}\"\n\t\t\t);\n\n\t\t\tvar reconnected = await WithTimeout(reconnectReceived.Task, 10000);\n\t\t\tAssert.IsTrue(reconnected, \"Should reconnect successfully\");\n\n\t\t\t// Verify state is preserved after reconnection\n\t\t\tawait Task.Delay(200);\n\t\t\tvar self = room.State.players[room.SessionId];\n\t\t\tAssert.IsNotNull(self, \"Player should still exist after reconnection\");\n\t\t\tAssert.AreEqual(42f, self.x, \"X position should be preserved\");\n\t\t\tAssert.AreEqual(84f, self.y, \"Y position should be preserved\");\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Reconnection_PlayerDisconnectedFlag()\n\t\t{\n\t\t\tvar client2 = new Client(\"ws://localhost:2567\");\n\n\t\t\tvar room1 = await client.Create<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived1 = new TaskCompletionSource<bool>();\n\n\t\t\troom1.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived1.Task.IsCompleted)\n\t\t\t\t\tstateReceived1.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived1.Task, 5000);\n\n\t\t\tvar room2 = await client2.JoinById<MyRoomState>(room1.RoomId);\n\t\t\tawait Task.Delay(500);\n\n\t\t\t// Delay reconnection so we can observe the disconnected flag\n\t\t\troom2.Reconnection.MinUptime = 0;\n\t\t\troom2.Reconnection.MinDelay = 2000;\n\t\t\troom2.Reconnection.Delay = 2000;\n\n\t\t\t// Drop client2's connection\n\t\t\troom2.Connection.Drop();\n\n\t\t\t// Wait for room1 to see the disconnected flag\n\t\t\tawait Task.Delay(1000);\n\t\t\tvar player2InRoom1 = room1.State.players[room2.SessionId];\n\t\t\tAssert.IsNotNull(player2InRoom1, \"Player2 should still exist (waiting for reconnect)\");\n\t\t\tAssert.IsTrue(player2InRoom1.disconnected, \"Player2 should be marked as disconnected\");\n\n\t\t\t// Wait for room2 to reconnect\n\t\t\tvar reconnectReceived = new TaskCompletionSource<bool>();\n\t\t\troom2.OnReconnect += () =>\n\t\t\t{\n\t\t\t\tif (!reconnectReceived.Task.IsCompleted)\n\t\t\t\t\treconnectReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(reconnectReceived.Task, 10000);\n\t\t\tawait Task.Delay(500);\n\n\t\t\t// Verify disconnected flag is cleared\n\t\t\tplayer2InRoom1 = room1.State.players[room2.SessionId];\n\t\t\tAssert.IsFalse(player2InRoom1.disconnected, \"Player2 should no longer be disconnected\");\n\n\t\t\tawait room1.Leave();\n\t\t\tawait room2.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Reconnection_SendMessageAfterReconnect()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tvar reconnectReceived = new TaskCompletionSource<bool>();\n\t\t\troom.OnReconnect += () =>\n\t\t\t{\n\t\t\t\tif (!reconnectReceived.Task.IsCompleted)\n\t\t\t\t\treconnectReceived.TrySetResult(true);\n\t\t\t};\n\n\t\t\troom.Reconnection.MinUptime = 0;\n\t\t\troom.Connection.Drop();\n\n\t\t\tawait WithTimeout(reconnectReceived.Task, 10000);\n\n\t\t\t// Send a message after reconnection\n\t\t\tawait room.Send(\"move\", new { x = 999, y = 888 });\n\t\t\tawait Task.Delay(200);\n\n\t\t\tvar self = room.State.players[room.SessionId];\n\t\t\tAssert.AreEqual(999f, self.x, \"Should process messages after reconnect\");\n\t\t\tAssert.AreEqual(888f, self.y, \"Should process messages after reconnect\");\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Callbacks_OnAdd_OnRemove_Players()\n\t\t{\n\t\t\tvar client2 = new Client(\"ws://localhost:2567\");\n\n\t\t\tvar room1 = await client.Create<MyRoomState>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom1.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tvar callbacks = Callbacks.Get(room1);\n\n\t\t\tvar addedSessionIds = new List<string>();\n\t\t\tvar removedSessionIds = new List<string>();\n\n\t\t\tcallbacks.OnAdd(state => state.players, (sessionId, player) =>\n\t\t\t{\n\t\t\t\taddedSessionIds.Add(sessionId);\n\t\t\t});\n\n\t\t\tcallbacks.OnRemove(state => state.players, (sessionId, player) =>\n\t\t\t{\n\t\t\t\tremovedSessionIds.Add(sessionId);\n\t\t\t});\n\n\t\t\t// Self should already trigger onAdd\n\t\t\tAssert.Contains(room1.SessionId, addedSessionIds);\n\n\t\t\t// Second client joins\n\t\t\tvar room2 = await client2.JoinById<MyRoomState>(room1.RoomId);\n\t\t\tawait Task.Delay(500);\n\n\t\t\tAssert.Contains(room2.SessionId, addedSessionIds);\n\t\t\tAssert.AreEqual(2, addedSessionIds.Count);\n\n\t\t\t// Second client leaves\n\t\t\ttry { await room2.Leave(); } catch (TaskCanceledException) { }\n\t\t\tawait Task.Delay(500);\n\n\t\t\tAssert.Contains(room2.SessionId, removedSessionIds);\n\t\t\tAssert.AreEqual(1, removedSessionIds.Count);\n\n\t\t\ttry { await room1.Leave(); } catch (TaskCanceledException) { }\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task JoinRoom_DynamicSchema()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<DynamicSchema>(\"my_room\");\n\n\t\t\tAssert.IsNotNull(room);\n\t\t\tAssert.IsNotNull(room.RoomId);\n\t\t\tAssert.IsNotNull(room.SessionId);\n\t\t\tAssert.AreEqual(\"my_room\", room.Name);\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ReceiveInitialState_DynamicSchema()\n\t\t{\n\t\t\tvar room = await client.JoinOrCreate<DynamicSchema>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\n\t\t\tvar received = await WithTimeout(stateReceived.Task, 5000);\n\t\t\tAssert.IsTrue(received, \"Should receive initial state\");\n\n\t\t\tvar players = room.State.Get<MapSchema<DynamicSchema>>(\"players\");\n\t\t\tAssert.IsNotNull(players);\n\t\t\tAssert.IsTrue(players.Count >= 1, \"Should have at least 1 player (self)\");\n\t\t\tAssert.IsNotNull(players[room.SessionId], \"Player should exist with own sessionId\");\n\n\t\t\t// Player should have an initial item (sword)\n\t\t\tvar self = players[room.SessionId];\n\t\t\tvar items = self.Get<ArraySchema<DynamicSchema>>(\"items\");\n\t\t\tAssert.AreEqual(1, items.Count);\n\t\t\tAssert.AreEqual(\"sword\", items[0].Get<string>(\"name\"));\n\n\t\t\tawait room.Leave();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Callbacks_OnAdd_OnRemove_Players_DynamicSchema()\n\t\t{\n\t\t\tvar client2 = new Client(\"ws://localhost:2567\");\n\n\t\t\tvar room1 = await client.Create<DynamicSchema>(\"my_room\");\n\t\t\tvar stateReceived = new TaskCompletionSource<bool>();\n\n\t\t\troom1.OnStateChange += (state, isFirstState) =>\n\t\t\t{\n\t\t\t\tif (isFirstState && !stateReceived.Task.IsCompleted)\n\t\t\t\t\tstateReceived.TrySetResult(true);\n\t\t\t};\n\t\t\tawait WithTimeout(stateReceived.Task, 5000);\n\n\t\t\tvar callbacks = Callbacks.Get(room1);\n\n\t\t\tvar addedSessionIds = new List<string>();\n\t\t\tvar removedSessionIds = new List<string>();\n\n\t\t\tcallbacks.OnAdd<DynamicSchema>(\"players\", (sessionId, player) =>\n\t\t\t{\n\t\t\t\taddedSessionIds.Add(sessionId);\n\t\t\t});\n\n\t\t\tcallbacks.OnRemove<DynamicSchema>(\"players\", (sessionId, player) =>\n\t\t\t{\n\t\t\t\tremovedSessionIds.Add(sessionId);\n\t\t\t});\n\n\t\t\t// Self should already trigger onAdd\n\t\t\tAssert.Contains(room1.SessionId, addedSessionIds);\n\n\t\t\t// Second client joins\n\t\t\tvar room2 = await client2.JoinById<DynamicSchema>(room1.RoomId);\n\t\t\tawait Task.Delay(500);\n\n\t\t\tAssert.Contains(room2.SessionId, addedSessionIds);\n\t\t\tAssert.AreEqual(2, addedSessionIds.Count);\n\n\t\t\t// Second client leaves\n\t\t\tawait room2.Leave();\n\t\t\tawait Task.Delay(500);\n\n\t\t\tAssert.Contains(room2.SessionId, removedSessionIds);\n\t\t\tAssert.AreEqual(1, removedSessionIds.Count);\n\n\t\t\tawait room1.Leave();\n\t\t}\n\n\t\tprivate async Task<T> WithTimeout<T>(Task<T> task, int timeoutMs)\n\t\t{\n\t\t\tusing var cts = new CancellationTokenSource(timeoutMs);\n\t\t\tvar completedTask = await Task.WhenAny(task, Task.Delay(timeoutMs, cts.Token));\n\t\t\tif (completedTask == task)\n\t\t\t{\n\t\t\t\tcts.Cancel();\n\t\t\t\treturn await task;\n\t\t\t}\n\t\t\treturn default;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/IntegrationTest.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1dd617ab4c23b4a6fabaae0ab001d1d6"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaClear/ArraySchemaClear.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ArraySchemaClear {\n\tpublic partial class ArraySchemaClear : Schema {\n\t\t[Type(0, \"array\", typeof(ArraySchema<float>), \"number\")]\n\t\tpublic ArraySchema<float> items = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaClear/ArraySchemaClear.cs.meta",
    "content": "fileFormatVersion: 2\nguid: efb6c56f75f5d41e692dc5309b0c6c4d"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaClear.meta",
    "content": "fileFormatVersion: 2\nguid: fb0074debb8384795a731ee7c4385cb3\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice/Item.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 1.0.24\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ArraySchemaMultipleSplice {\n\tpublic partial class Item : Schema {\n\t\t[Type(0, \"string\")]\n\t\tpublic string name = default(string);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice/Item.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 4b7bdbaefecf04283828900305de33ef"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice/MultipleArraySpliceState.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 1.0.24\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ArraySchemaMultipleSplice {\n\tpublic partial class MultipleArraySpliceState : Schema {\n\t\t[Type(0, \"ref\", typeof(Player))]\n\t\tpublic Player player = new Player();\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice/MultipleArraySpliceState.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1f1a24dd33355499f91b2bb008505f1b"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 1.0.24\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ArraySchemaMultipleSplice {\n\tpublic partial class Player : Schema {\n\t\t[Type(0, \"array\", typeof(ArraySchema<Item>))]\n\t\tpublic ArraySchema<Item> items = new ArraySchema<Item>();\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ad4f86486859c42aeaf0d80f1507f038"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaMultipleSplice.meta",
    "content": "fileFormatVersion: 2\nguid: 96d4e1107ea454d60a3f698ce9946363\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaTypes/ArraySchemaTypes.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ArraySchemaTypes {\n\tpublic partial class ArraySchemaTypes : Schema {\n\t\t[Type(0, \"array\", typeof(ArraySchema<IAmAChild>))]\n\t\tpublic ArraySchema<IAmAChild> arrayOfSchemas = null;\n\n\t\t[Type(1, \"array\", typeof(ArraySchema<float>), \"number\")]\n\t\tpublic ArraySchema<float> arrayOfNumbers = null;\n\n\t\t[Type(2, \"array\", typeof(ArraySchema<string>), \"string\")]\n\t\tpublic ArraySchema<string> arrayOfStrings = null;\n\n\t\t[Type(3, \"array\", typeof(ArraySchema<int>), \"int32\")]\n\t\tpublic ArraySchema<int> arrayOfInt32 = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaTypes/ArraySchemaTypes.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a3927ef0021c52b4196710583e49c484"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaTypes/IAmAChild.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ArraySchemaTypes {\n\tpublic partial class IAmAChild : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaTypes/IAmAChild.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 9f1340b75f249704e855879ab42d8f48"
  },
  {
    "path": "nuget/tests/Schema/ArraySchemaTypes.meta",
    "content": "fileFormatVersion: 2\nguid: c3adda012959e4e0a846dd5cfdcdea15\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/PlayerV1.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.BackwardsForwards {\n\tpublic partial class PlayerV1 : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/PlayerV1.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1e608157ebaa98c4d8fe1d0ed75f23b0"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/PlayerV2.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.BackwardsForwards {\n\tpublic partial class PlayerV2 : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\n\t\t[Type(2, \"string\")]\n\t\tpublic string name = default(string);\n\n\t\t[Type(3, \"array\", typeof(ArraySchema<string>), \"string\")]\n\t\tpublic ArraySchema<string> arrayOfStrings = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/PlayerV2.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a3492361ef7f0764ca8b5b9fc9cf0a61"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/StateV1.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.BackwardsForwards {\n\tpublic partial class StateV1 : Schema {\n\t\t[Type(0, \"string\")]\n\t\tpublic string str = default(string);\n\n\t\t[Type(1, \"map\", typeof(MapSchema<PlayerV1>))]\n\t\tpublic MapSchema<PlayerV1> map = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/StateV1.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e762e861c5ad4ea448baff51e42da830"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/StateV2.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.BackwardsForwards {\n\tpublic partial class StateV2 : Schema {\n\t\t[Type(0, \"string\")]\n\t\tpublic string str = default(string);\n\n\t\t[System.Obsolete(\"field 'map' is deprecated.\", true)]\n\t\t[Type(1, \"map\", typeof(MapSchema<PlayerV2>))]\n\t\tpublic MapSchema<PlayerV2> map = null;\n\n\t\t[Type(2, \"number\")]\n\t\tpublic float countdown = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards/StateV2.cs.meta",
    "content": "fileFormatVersion: 2\nguid: f65997833ffe1394bbf8086ce588a544"
  },
  {
    "path": "nuget/tests/Schema/BackwardsForwards.meta",
    "content": "fileFormatVersion: 2\nguid: e5fc27d8b2ee949278f5888c893e2dfe\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/CallbacksState.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.45\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.Callbacks {\n\tpublic partial class CallbacksState : Schema {\n\t\t[Type(0, \"ref\", typeof(Container))]\n\t\tpublic Container container = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/CallbacksState.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 10d4dc8bba33dd94a82db82146eb2b11"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Container.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.45\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.Callbacks {\n\tpublic partial class Container : Schema {\n\t\t[Type(0, \"map\", typeof(MapSchema<Player>))]\n\t\tpublic MapSchema<Player> playersMap = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Container.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 541e8baeb06ddf04ca6c884331adb0ac"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Item.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.45\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.Callbacks {\n\tpublic partial class Item : Schema {\n\t\t[Type(0, \"string\")]\n\t\tpublic string name = default(string);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float value = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Item.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 440bd948df0ba43f09c259a18f200cf3"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.45\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.Callbacks {\n\tpublic partial class Player : Schema {\n\t\t[Type(0, \"ref\", typeof(Vec3))]\n\t\tpublic Vec3 position = null;\n\n\t\t[Type(1, \"map\", typeof(MapSchema<Item>))]\n\t\tpublic MapSchema<Item> items = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e9172e24746504b44b7b798eed84ec22"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Vec3.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.45\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.Callbacks {\n\tpublic partial class Vec3 : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\n\t\t[Type(2, \"number\")]\n\t\tpublic float z = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/Callbacks/Vec3.cs.meta",
    "content": "fileFormatVersion: 2\nguid: face922d9afe44f4cad0bdcf506493e4"
  },
  {
    "path": "nuget/tests/Schema/Callbacks.meta",
    "content": "fileFormatVersion: 2\nguid: ce95c7363114341e99ddcbfe8b308fbc\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/ChildSchemaTypes/ChildSchemaTypes.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ChildSchemaTypes {\n\tpublic partial class ChildSchemaTypes : Schema {\n\t\t[Type(0, \"ref\", typeof(IAmAChild))]\n\t\tpublic IAmAChild child = null;\n\n\t\t[Type(1, \"ref\", typeof(IAmAChild))]\n\t\tpublic IAmAChild secondChild = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ChildSchemaTypes/ChildSchemaTypes.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 46de100349a4e614dabe1c75c026bc3d"
  },
  {
    "path": "nuget/tests/Schema/ChildSchemaTypes/IAmAChild.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.ChildSchemaTypes {\n\tpublic partial class IAmAChild : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/ChildSchemaTypes/IAmAChild.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 30300a95b05cc9948adb45e084ca728e"
  },
  {
    "path": "nuget/tests/Schema/ChildSchemaTypes.meta",
    "content": "fileFormatVersion: 2\nguid: 6946701a252264a3086bc0c141bc2366\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/FilteredTypes/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.FilteredTypes {\n\tpublic partial class Player : Schema {\n\t\t[Type(0, \"string\")]\n\t\tpublic string name = default(string);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/FilteredTypes/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: bc4974b234009414d8fd3ff376e4b1c2"
  },
  {
    "path": "nuget/tests/Schema/FilteredTypes/State.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.FilteredTypes {\n\tpublic partial class State : Schema {\n\t\t[Type(0, \"ref\", typeof(Player))]\n\t\tpublic Player playerOne = null;\n\n\t\t[Type(1, \"ref\", typeof(Player))]\n\t\tpublic Player playerTwo = null;\n\n\t\t[Type(2, \"array\", typeof(ArraySchema<Player>))]\n\t\tpublic ArraySchema<Player> players = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/FilteredTypes/State.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 2c4b58757e908dd45be8b14bd9e24240"
  },
  {
    "path": "nuget/tests/Schema/FilteredTypes.meta",
    "content": "fileFormatVersion: 2\nguid: 64881287456fa4a5d88b9f3c9a5dcfee\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/Bot.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InheritedTypes {\n\tpublic partial class Bot : Player {\n\t\t[Type(3, \"number\")]\n\t\tpublic float power = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/Bot.cs.meta",
    "content": "fileFormatVersion: 2\nguid: c3c3f288bd67b9245a5ce84735e31bdb"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/Entity.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InheritedTypes {\n\tpublic partial class Entity : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/Entity.cs.meta",
    "content": "fileFormatVersion: 2\nguid: f46d8182fac8cd241a7f3276255ca903"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/InheritedTypes.cs",
    "content": "//\n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n//\n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n//\n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InheritedTypes {\n\tpublic partial class InheritedTypes : Schema {\n\t\t[Type(0, \"ref\", typeof(Entity))]\n\t\tpublic Entity entity = null;\n\n\t\t[Type(1, \"ref\", typeof(Player))]\n\t\tpublic Player player = null;\n\n\t\t[Type(2, \"ref\", typeof(Bot))]\n\t\tpublic Bot bot = null;\n\n\t\t[Type(3, \"ref\", typeof(Entity))]\n\t\tpublic Entity any = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/InheritedTypes.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 53219bd4741d8b54a870c7133650fb0e"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InheritedTypes {\n\tpublic partial class Player : Entity {\n\t\t[Type(2, \"string\")]\n\t\tpublic string name = default(string);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: dc399e0dbf94ed845877a4c73a7651ec"
  },
  {
    "path": "nuget/tests/Schema/InheritedTypes.meta",
    "content": "fileFormatVersion: 2\nguid: 58ba81f9d6c3049de8c9e6b48d494636\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InstanceSharingTypes {\n\tpublic partial class Player : Schema {\n\t\t[Type(0, \"ref\", typeof(Position))]\n\t\tpublic Position position = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: d62eb91e2d260a64e90ab3a7cdcc5cb7"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes/Position.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InstanceSharingTypes {\n\tpublic partial class Position : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes/Position.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 766571b4ac054a446829d35adf3f9a72"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes/State.cs",
    "content": "//\n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n//\n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n//\n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.InstanceSharingTypes {\n\tpublic partial class State : Schema {\n\t\t[Type(0, \"ref\", typeof(Player))]\n\t\tpublic Player player1 = null;\n\n\t\t[Type(1, \"ref\", typeof(Player))]\n\t\tpublic Player player2 = null;\n\n\t\t[Type(2, \"array\", typeof(ArraySchema<Player>))]\n\t\tpublic ArraySchema<Player> arrayOfPlayers = null;\n\n\t\t[Type(3, \"map\", typeof(MapSchema<Player>))]\n\t\tpublic MapSchema<Player> mapOfPlayers = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes/State.cs.meta",
    "content": "fileFormatVersion: 2\nguid: f2b5eaaa9a8f1fe41a4fb27f451b0937"
  },
  {
    "path": "nuget/tests/Schema/InstanceSharingTypes.meta",
    "content": "fileFormatVersion: 2\nguid: 664875c2b40d24cea818044701949bfa\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/Item.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 4.0.7\n// \n\nusing Colyseus.Schema;\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine.Scripting;\n#endif\n\npublic partial class Item : Schema {\n#if UNITY_5_3_OR_NEWER\n[Preserve]\n#endif\npublic Item() { }\n\t[Type(0, \"string\")]\n\tpublic string name = default(string);\n\n\t[Type(1, \"number\")]\n\tpublic float value = default(float);\n}\n\n"
  },
  {
    "path": "nuget/tests/Schema/Item.cs.meta",
    "content": "fileFormatVersion: 2\nguid: a5434d2f269ce49ae8f236757533aac8"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaInt8/MapSchemaInt8.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.MapSchemaInt8 {\n\tpublic partial class MapSchemaInt8 : Schema {\n\t\t[Type(0, \"string\")]\n\t\tpublic string status = default(string);\n\n\t\t[Type(1, \"map\", typeof(MapSchema<sbyte>), \"int8\")]\n\t\tpublic MapSchema<sbyte> mapOfInt8 = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaInt8/MapSchemaInt8.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 08bbf096d257fa74bb2ffc19538fafb9"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaInt8.meta",
    "content": "fileFormatVersion: 2\nguid: 251e6c825126f4972bd0e7449445757d\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaMoveNullifyType/State.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.MapSchemaMoveNullifyType {\n\tpublic partial class State : Schema {\n\t\t[Type(0, \"map\", typeof(MapSchema<float>), \"number\")]\n\t\tpublic MapSchema<float> previous = null;\n\n\t\t[Type(1, \"map\", typeof(MapSchema<float>), \"number\")]\n\t\tpublic MapSchema<float> current = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaMoveNullifyType/State.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 8eb639901cc8eeb428128815a12eb093"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaMoveNullifyType.meta",
    "content": "fileFormatVersion: 2\nguid: 85d943bc466e24cfa9226aa0f1856e32\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaTypes/IAmAChild.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.MapSchemaTypes {\n\tpublic partial class IAmAChild : Schema {\n\t\t[Type(0, \"number\")]\n\t\tpublic float x = default(float);\n\n\t\t[Type(1, \"number\")]\n\t\tpublic float y = default(float);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaTypes/IAmAChild.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 90a7e6eba5991bf478ca7a73f485a4d2"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaTypes/MapSchemaTypes.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.MapSchemaTypes {\n\tpublic partial class MapSchemaTypes : Schema {\n\t\t[Type(0, \"map\", typeof(MapSchema<IAmAChild>))]\n\t\tpublic MapSchema<IAmAChild> mapOfSchemas = null;\n\n\t\t[Type(1, \"map\", typeof(MapSchema<float>), \"number\")]\n\t\tpublic MapSchema<float> mapOfNumbers = null;\n\n\t\t[Type(2, \"map\", typeof(MapSchema<string>), \"string\")]\n\t\tpublic MapSchema<string> mapOfStrings = null;\n\n\t\t[Type(3, \"map\", typeof(MapSchema<int>), \"int32\")]\n\t\tpublic MapSchema<int> mapOfInt32 = null;\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaTypes/MapSchemaTypes.cs.meta",
    "content": "fileFormatVersion: 2\nguid: f37944f2f0e8234479f7b069caa80b6b"
  },
  {
    "path": "nuget/tests/Schema/MapSchemaTypes.meta",
    "content": "fileFormatVersion: 2\nguid: 16a64debc13484ba3bc6ead2277ccf57\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema/MyRoomState.cs",
    "content": "//\n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n//\n// GENERATED USING @colyseus/schema 4.0.7\n//\n\nusing Colyseus.Schema;\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine.Scripting;\n#endif\n\npublic partial class MyRoomState : Schema {\n#if UNITY_5_3_OR_NEWER\n[Preserve]\n#endif\npublic MyRoomState() { }\n\t[Type(0, \"map\", typeof(MapSchema<Player>))]\n\tpublic MapSchema<Player> players = null;\n\n\t[Type(1, \"ref\", typeof(Player))]\n\tpublic Player host = null;\n\n\t[Type(2, \"string\")]\n\tpublic string currentTurn = default(string);\n}\n\n"
  },
  {
    "path": "nuget/tests/Schema/MyRoomState.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e9fff1bd47aac4e678f9f8aa1d39aa62"
  },
  {
    "path": "nuget/tests/Schema/Player.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 4.0.7\n// \n\nusing Colyseus.Schema;\n#if UNITY_5_3_OR_NEWER\nusing UnityEngine.Scripting;\n#endif\n\npublic partial class Player : Schema {\n#if UNITY_5_3_OR_NEWER\n[Preserve]\n#endif\npublic Player() { }\n\t[Type(0, \"number\")]\n\tpublic float x = default(float);\n\n\t[Type(1, \"number\")]\n\tpublic float y = default(float);\n\n\t[Type(2, \"boolean\")]\n\tpublic bool isBot = default(bool);\n\n\t[Type(3, \"boolean\")]\n\tpublic bool disconnected = default(bool);\n\n\t[Type(4, \"array\", typeof(ArraySchema<Item>))]\n\tpublic ArraySchema<Item> items = null;\n}\n\n"
  },
  {
    "path": "nuget/tests/Schema/Player.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 1b23527f145f54602bb507f95baa577a"
  },
  {
    "path": "nuget/tests/Schema/PrimitiveTypes/PrimitiveTypes.cs",
    "content": "// \n// THIS FILE HAS BEEN GENERATED AUTOMATICALLY\n// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING\n// \n// GENERATED USING @colyseus/schema 3.0.0-alpha.40\n// \n\nusing Colyseus.Schema;\n\nnamespace SchemaTest.PrimitiveTypes {\n\tpublic partial class PrimitiveTypes : Schema {\n\t\t[Type(0, \"int8\")]\n\t\tpublic sbyte int8 = default(sbyte);\n\n\t\t[Type(1, \"uint8\")]\n\t\tpublic byte uint8 = default(byte);\n\n\t\t[Type(2, \"int16\")]\n\t\tpublic short int16 = default(short);\n\n\t\t[Type(3, \"uint16\")]\n\t\tpublic ushort uint16 = default(ushort);\n\n\t\t[Type(4, \"int32\")]\n\t\tpublic int int32 = default(int);\n\n\t\t[Type(5, \"uint32\")]\n\t\tpublic uint uint32 = default(uint);\n\n\t\t[Type(6, \"int64\")]\n\t\tpublic long int64 = default(long);\n\n\t\t[Type(7, \"uint64\")]\n\t\tpublic ulong uint64 = default(ulong);\n\n\t\t[Type(8, \"float32\")]\n\t\tpublic float float32 = default(float);\n\n\t\t[Type(9, \"float64\")]\n\t\tpublic double float64 = default(double);\n\n\t\t[Type(10, \"number\")]\n\t\tpublic float varint_int8 = default(float);\n\n\t\t[Type(11, \"number\")]\n\t\tpublic float varint_uint8 = default(float);\n\n\t\t[Type(12, \"number\")]\n\t\tpublic float varint_int16 = default(float);\n\n\t\t[Type(13, \"number\")]\n\t\tpublic float varint_uint16 = default(float);\n\n\t\t[Type(14, \"number\")]\n\t\tpublic float varint_int32 = default(float);\n\n\t\t[Type(15, \"number\")]\n\t\tpublic float varint_uint32 = default(float);\n\n\t\t[Type(16, \"number\")]\n\t\tpublic float varint_int64 = default(float);\n\n\t\t[Type(17, \"number\")]\n\t\tpublic float varint_uint64 = default(float);\n\n\t\t[Type(18, \"number\")]\n\t\tpublic float varint_float32 = default(float);\n\n\t\t[Type(19, \"number\")]\n\t\tpublic float varint_float64 = default(float);\n\n\t\t[Type(20, \"string\")]\n\t\tpublic string str = default(string);\n\n\t\t[Type(21, \"boolean\")]\n\t\tpublic bool boolean = default(bool);\n\t}\n}\n"
  },
  {
    "path": "nuget/tests/Schema/PrimitiveTypes/PrimitiveTypes.cs.meta",
    "content": "fileFormatVersion: 2\nguid: 9337f20e96c6911449e3eaeeb2caa451"
  },
  {
    "path": "nuget/tests/Schema/PrimitiveTypes.meta",
    "content": "fileFormatVersion: 2\nguid: 1932739676ae34fcb94ed29a8b6c8c37\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/Schema.meta",
    "content": "fileFormatVersion: 2\nguid: e239053f82903c846802ac1616263fcc\nfolderAsset: yes\nDefaultImporter:\n  externalObjects: {}\n  userData: \n  assetBundleName: \n  assetBundleVariant: \n"
  },
  {
    "path": "nuget/tests/SchemaDeserializerTest.cs",
    "content": "using NUnit.Framework;\nusing Colyseus.Schema;\n\nnamespace Colyseus.Tests\n{\n\n\t[TestFixture]\n\tpublic class SchemaDeserializerTest\n\t{\n\n\t\t[Test]\n\t\tpublic void PrimitiveTypesTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.PrimitiveTypes.PrimitiveTypes>();\n\t\t\tvar state = decoder.State;\n\t\t\tbyte[] bytes = { 128, 128, 129, 255, 130, 0, 128, 131, 255, 255, 132, 0, 0, 0, 128, 133, 255, 255, 255, 255, 134, 0, 0, 0, 0, 0, 0, 0, 128, 135, 255, 255, 255, 255, 255, 255, 31, 0, 136, 204, 204, 204, 253, 137, 255, 255, 255, 255, 255, 255, 239, 127, 138, 208, 128, 139, 204, 255, 140, 209, 0, 128, 141, 205, 255, 255, 142, 210, 0, 0, 0, 128, 143, 203, 0, 0, 224, 255, 255, 255, 239, 65, 144, 203, 0, 0, 0, 0, 0, 0, 224, 195, 145, 203, 255, 255, 255, 255, 255, 255, 63, 67, 146, 203, 61, 255, 145, 224, 255, 255, 239, 199, 147, 203, 153, 153, 153, 153, 153, 153, 185, 127, 148, 171, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 149, 1 };\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tAssert.AreEqual(state.int8, -128);\n\t\t\tAssert.AreEqual(state.uint8, 255);\n\t\t\tAssert.AreEqual(state.int16, -32768);\n\t\t\tAssert.AreEqual(state.uint16, 65535);\n\t\t\tAssert.AreEqual(state.int32, -2147483648);\n\t\t\tAssert.AreEqual(state.uint32, 4294967295);\n\t\t\tAssert.AreEqual(state.int64, -9223372036854775808);\n\t\t\tAssert.AreEqual(state.uint64, 9007199254740991);\n\t\t\tAssert.AreEqual(state.float32, -3.40282347E+37f);\n\t\t\tAssert.AreEqual(state.float64, 1.7976931348623157e+308);\n\n\t\t\tAssert.AreEqual(state.varint_int8, -128);\n\t\t\tAssert.AreEqual(state.varint_uint8, 255);\n\t\t\tAssert.AreEqual(state.varint_int16, -32768);\n\t\t\tAssert.AreEqual(state.varint_uint16, 65535);\n\t\t\tAssert.AreEqual(state.varint_int32, -2147483648);\n\t\t\tAssert.AreEqual(state.varint_uint32, 4294967295);\n\t\t\tAssert.AreEqual(state.varint_int64, -9223372036854775808);\n\t\t\tAssert.AreEqual(state.varint_uint64, 9007199254740991);\n\t\t\tAssert.AreEqual(state.varint_float32, -3.40282347E+38f);\n\t\t\tAssert.AreEqual(state.varint_float64, float.PositiveInfinity);\n\n\t\t\tAssert.AreEqual(state.str, \"Hello world\");\n\t\t\tAssert.AreEqual(state.boolean, true);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ChildSchemaTypesTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.ChildSchemaTypes.ChildSchemaTypes>();\n\t\t\tvar state = decoder.State;\n\t\t\tbyte[] bytes = { 128, 1, 129, 2, 255, 1, 128, 205, 244, 1, 129, 205, 32, 3, 255, 2, 128, 204, 200, 129, 205, 44, 1 };\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tAssert.AreEqual(state.child.x, 500);\n\t\t\tAssert.AreEqual(state.child.y, 800);\n\n\t\t\tAssert.AreEqual(state.secondChild.x, 200);\n\t\t\tAssert.AreEqual(state.secondChild.y, 300);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ArraySchemaTypesTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.ArraySchemaTypes.ArraySchemaTypes>();\n\t\t\tvar state = decoder.State;\n\t\t\tbyte[] bytes = { 128, 1, 129, 2, 130, 3, 131, 4, 255, 1, 128, 0, 5, 128, 1, 6, 255, 2, 128, 0, 0, 128, 1, 10, 128, 2, 20, 128, 3, 205, 192, 13, 255, 3, 128, 0, 163, 111, 110, 101, 128, 1, 163, 116, 119, 111, 128, 2, 165, 116, 104, 114, 101, 101, 255, 4, 128, 0, 232, 3, 0, 0, 128, 1, 192, 13, 0, 0, 128, 2, 72, 244, 255, 255, 255, 5, 128, 100, 129, 208, 156, 255, 6, 128, 100, 129, 208, 156 };\n\n\t\t\tvar callbacks = Colyseus.Schema.Callbacks.Get(decoder);\n\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tvar arrayOfSchemasOnAdd = 0;\n\t\t\tvar arrayOfNumbersOnAdd = 0;\n\t\t\tvar arrayOfStringsOnAdd = 0;\n\t\t\tvar arrayOfInt32OnAdd = 0;\n\n\t\t\tcallbacks.OnAdd(state => state.arrayOfSchemas, (key, value) => arrayOfSchemasOnAdd++);\n\t\t\tcallbacks.OnAdd(state => state.arrayOfNumbers, (key, value) => arrayOfNumbersOnAdd++);\n\t\t\tcallbacks.OnAdd(state => state.arrayOfStrings, (key, value) => arrayOfStringsOnAdd++);\n\t\t\tcallbacks.OnAdd(state => state.arrayOfInt32, (key, value) => arrayOfInt32OnAdd++);\n\n\t\t\tAssert.AreEqual(2, arrayOfSchemasOnAdd);\n\t\t\tAssert.AreEqual(4, arrayOfNumbersOnAdd);\n\t\t\tAssert.AreEqual(3, arrayOfStringsOnAdd);\n\t\t\tAssert.AreEqual(3, arrayOfInt32OnAdd);\n\n\t\t\tAssert.AreEqual(2, state.arrayOfSchemas.Count);\n\t\t\tAssert.AreEqual(100, state.arrayOfSchemas[0].x);\n\t\t\tAssert.AreEqual(-100, state.arrayOfSchemas[0].y);\n\t\t\tAssert.AreEqual(100, state.arrayOfSchemas[1].x);\n\t\t\tAssert.AreEqual(-100, state.arrayOfSchemas[1].y);\n\n\t\t\tAssert.AreEqual(4, state.arrayOfNumbers.Count);\n\t\t\tAssert.AreEqual(0, state.arrayOfNumbers[0]);\n\t\t\tAssert.AreEqual(10, state.arrayOfNumbers[1]);\n\t\t\tAssert.AreEqual(20, state.arrayOfNumbers[2]);\n\t\t\tAssert.AreEqual(3520, state.arrayOfNumbers[3]);\n\n\t\t\tAssert.AreEqual(3, state.arrayOfStrings.Count);\n\t\t\tAssert.AreEqual(\"one\", state.arrayOfStrings[0]);\n\t\t\tAssert.AreEqual(\"two\", state.arrayOfStrings[1]);\n\t\t\tAssert.AreEqual(\"three\", state.arrayOfStrings[2]);\n\n\t\t\tAssert.AreEqual(3, state.arrayOfInt32.Count);\n\t\t\tAssert.AreEqual(1000, state.arrayOfInt32[0]);\n\t\t\tAssert.AreEqual(3520, state.arrayOfInt32[1]);\n\t\t\tAssert.AreEqual(-3000, state.arrayOfInt32[2]);\n\n\t\t\tvar arrayOfSchemasOnRemove = 0;\n\t\t\tvar arrayOfNumbersOnRemove = 0;\n\t\t\tvar arrayOfStringsOnRemove = 0;\n\t\t\tvar arrayOfInt32OnRemove = 0;\n\n\t\t\tcallbacks.OnRemove(state => state.arrayOfSchemas, (key, value) => arrayOfSchemasOnRemove++);\n\t\t\tcallbacks.OnRemove(state => state.arrayOfNumbers, (key, value) => arrayOfNumbersOnRemove++);\n\t\t\tcallbacks.OnRemove(state => state.arrayOfStrings, (key, value) => arrayOfStringsOnRemove++);\n\t\t\tcallbacks.OnRemove(state => state.arrayOfInt32, (key, value) => arrayOfInt32OnRemove++);\n\n\t\t\t// byte[] popBytes = { 255, 1, 64, 1, 255, 2, 64, 3, 64, 2, 64, 1, 255, 4, 64, 2, 64, 1, 255, 3, 64, 2, 64, 1 };\n\t\t\tbyte[] popBytes = { 255, 1, 64, 1, 255, 2, 64, 3, 64, 2, 64, 1, 255, 4, 64, 2, 64, 1, 255, 3, 64, 2, 64, 1 };\n\t\t\tdecoder.Decode(popBytes);\n\n\t\t\tAssert.AreEqual(1, state.arrayOfSchemas.Count);\n\t\t\tAssert.AreEqual(1, state.arrayOfNumbers.Count);\n\t\t\tAssert.AreEqual(1, state.arrayOfStrings.Count);\n\t\t\tAssert.AreEqual(1, state.arrayOfInt32.Count);\n\n\t\t\tAssert.AreEqual(1, arrayOfSchemasOnRemove);\n\t\t\tAssert.AreEqual(3, arrayOfNumbersOnRemove);\n\t\t\tAssert.AreEqual(2, arrayOfStringsOnRemove);\n\t\t\tAssert.AreEqual(2, arrayOfInt32OnRemove);\n\n\t\t\t// re-initialize ArraySchema's\n\t\t\tdecoder.Decode(new byte[] { 128, 7, 129, 8, 131, 9, 130, 10, 255, 7, 255, 8, 255, 9, 255, 10 });\n\t\t\tAssert.AreEqual(0, state.arrayOfSchemas.Count);\n\t\t\tAssert.AreEqual(0, state.arrayOfNumbers.Count);\n\t\t\tAssert.AreEqual(0, state.arrayOfStrings.Count);\n\t\t\tAssert.AreEqual(0, state.arrayOfInt32.Count);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ArraySchemaClearTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.ArraySchemaClear.ArraySchemaClear>();\n\t\t\tvar state = decoder.State;\n\t\t\tint onAddCount = 0;\n\t\t\tint onRemoveCount = 0;\n\n\t\t\tvar callbacks = Colyseus.Schema.Callbacks.Get(decoder);\n\t\t\tcallbacks.OnAdd(state => state.items, (key, value) => onAddCount++);\n\t\t\tcallbacks.OnRemove(state => state.items, (key, value) => onRemoveCount++);\n\n\t\t\tbyte[] bytes = { 128, 1, 255, 1, 128, 0, 1, 128, 1, 2, 128, 2, 3, 128, 3, 4, 128, 4, 5 };\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tAssert.AreEqual(5, onAddCount);\n\t\t\tAssert.AreEqual(0, onRemoveCount);\n\n\t\t\tbyte[] clearBytes = { 255, 1, 10, 255, 1 };\n\t\t\tdecoder.Decode(clearBytes);\n\n\t\t\tAssert.AreEqual(5, onAddCount);\n\t\t\tAssert.AreEqual(5, onRemoveCount);\n\n\t\t\tbyte[] reAddBytes = { 255, 1, 128, 0, 1, 128, 1, 2, 128, 2, 3, 128, 3, 4, 128, 4, 5, 255, 1, 255, 1 };\n\t\t\tdecoder.Decode(reAddBytes);\n\n\t\t\tAssert.AreEqual(10, onAddCount);\n\t\t\tAssert.AreEqual(5, onRemoveCount);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MapSchemaTypesTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.MapSchemaTypes.MapSchemaTypes>();\n\t\t\tvar state = decoder.State;\n\t\t\tbyte[] bytes = { 128, 1, 129, 2, 130, 3, 131, 4, 255, 1, 128, 0, 163, 111, 110, 101, 5, 128, 1, 163, 116, 119, 111, 6, 128, 2, 165, 116, 104, 114, 101, 101, 7, 255, 2, 128, 0, 163, 111, 110, 101, 1, 128, 1, 163, 116, 119, 111, 2, 128, 2, 165, 116, 104, 114, 101, 101, 205, 192, 13, 255, 3, 128, 0, 163, 111, 110, 101, 163, 79, 110, 101, 128, 1, 163, 116, 119, 111, 163, 84, 119, 111, 128, 2, 165, 116, 104, 114, 101, 101, 165, 84, 104, 114, 101, 101, 255, 4, 128, 0, 163, 111, 110, 101, 192, 13, 0, 0, 128, 1, 163, 116, 119, 111, 24, 252, 255, 255, 128, 2, 165, 116, 104, 114, 101, 101, 208, 7, 0, 0, 255, 5, 128, 100, 129, 204, 200, 255, 6, 128, 205, 44, 1, 129, 205, 144, 1, 255, 7, 128, 205, 244, 1, 129, 205, 88, 2 };\n\n\t\t\tvar callbacks = Colyseus.Schema.Callbacks.Get(decoder);\n\n\t\t\tvar mapOfSchemasAdd = 0;\n\t\t\tvar mapOfNumbersAdd = 0;\n\t\t\tvar mapOfStringsAdd = 0;\n\t\t\tvar mapOfIntAdd = 0;\n\t\t\tcallbacks.OnAdd(state => state.mapOfSchemas, (key, value) => mapOfSchemasAdd++);\n\t\t\tcallbacks.OnAdd(state => state.mapOfNumbers, (key, value) => mapOfNumbersAdd++);\n\t\t\tcallbacks.OnAdd(state => state.mapOfStrings, (key, value) => mapOfStringsAdd++);\n\t\t\tcallbacks.OnAdd(state => state.mapOfInt32, (key, value) => mapOfIntAdd++);\n\n\t\t\tvar mapOfSchemasRemove = 0;\n\t\t\tvar mapOfNumbersRemove = 0;\n\t\t\tvar mapOfStringsRemove = 0;\n\t\t\tvar mapOfIntRemove = 0;\n\t\t\tcallbacks.OnRemove(state => state.mapOfSchemas, (key, value) => mapOfSchemasRemove++);\n\t\t\tcallbacks.OnRemove(state => state.mapOfNumbers, (key, value) => mapOfNumbersRemove++);\n\t\t\tcallbacks.OnRemove(state => state.mapOfStrings, (key, value) => mapOfStringsRemove++);\n\t\t\tcallbacks.OnRemove(state => state.mapOfInt32, (key, value) => mapOfIntRemove++);\n\n\t\t\tvar mapOfSchemasChange = 0;\n\t\t\tvar mapOfNumbersChange = 0;\n\t\t\tvar mapOfStringsChange = 0;\n\t\t\tvar mapOfIntChange = 0;\n\t\t\tcallbacks.OnChange(state => state.mapOfSchemas, (key, value) => mapOfSchemasChange++);\n\t\t\tcallbacks.OnChange(state => state.mapOfNumbers, (key, value) => mapOfNumbersChange++);\n\t\t\tcallbacks.OnChange(state => state.mapOfStrings, (key, value) => mapOfStringsChange++);\n\t\t\tcallbacks.OnChange(state => state.mapOfInt32, (key, value) => mapOfIntChange++);\n\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tAssert.AreEqual(state.mapOfSchemas.Count, 3);\n\t\t\tAssert.AreEqual(state.mapOfSchemas[\"one\"].x, 100);\n\t\t\tAssert.AreEqual(state.mapOfSchemas[\"one\"].y, 200);\n\t\t\tAssert.AreEqual(state.mapOfSchemas[\"two\"].x, 300);\n\t\t\tAssert.AreEqual(state.mapOfSchemas[\"two\"].y, 400);\n\t\t\tAssert.AreEqual(state.mapOfSchemas[\"three\"].x, 500);\n\t\t\tAssert.AreEqual(state.mapOfSchemas[\"three\"].y, 600);\n\n\t\t\tAssert.AreEqual(state.mapOfNumbers.Count, 3);\n\t\t\tAssert.AreEqual(state.mapOfNumbers[\"one\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfNumbers[\"two\"], 2);\n\t\t\tAssert.AreEqual(state.mapOfNumbers[\"three\"], 3520);\n\n\t\t\tAssert.AreEqual(state.mapOfStrings.Count, 3);\n\t\t\tAssert.AreEqual(state.mapOfStrings[\"one\"], \"One\");\n\t\t\tAssert.AreEqual(state.mapOfStrings[\"two\"], \"Two\");\n\t\t\tAssert.AreEqual(state.mapOfStrings[\"three\"], \"Three\");\n\n\t\t\tAssert.AreEqual(state.mapOfInt32.Count, 3);\n\t\t\tAssert.AreEqual(state.mapOfInt32[\"one\"], 3520);\n\t\t\tAssert.AreEqual(state.mapOfInt32[\"two\"], -1000);\n\t\t\tAssert.AreEqual(state.mapOfInt32[\"three\"], 2000);\n\n\t\t\tAssert.AreEqual(mapOfSchemasAdd, 3);\n\t\t\tAssert.AreEqual(mapOfNumbersAdd, 3);\n\t\t\tAssert.AreEqual(mapOfStringsAdd, 3);\n\t\t\tAssert.AreEqual(mapOfIntAdd, 3);\n\n\t\t\tbyte[] deleteBytes = { 255, 2, 64, 1, 64, 2, 255, 1, 64, 1, 64, 2, 255, 3, 64, 1, 64, 2, 255, 4, 64, 1, 64, 2 };\n\t\t\tdecoder.Decode(deleteBytes);\n\n\t\t\tAssert.AreEqual(state.mapOfSchemas.Count, 1);\n\t\t\tAssert.AreEqual(state.mapOfNumbers.Count, 1);\n\t\t\tAssert.AreEqual(state.mapOfStrings.Count, 1);\n\t\t\tAssert.AreEqual(state.mapOfInt32.Count, 1);\n\n\t\t\tAssert.AreEqual(mapOfSchemasRemove, 2);\n\t\t\tAssert.AreEqual(mapOfNumbersRemove, 2);\n\t\t\tAssert.AreEqual(mapOfStringsRemove, 2);\n\t\t\tAssert.AreEqual(mapOfIntRemove, 2);\n\n\t\t\tAssert.AreEqual(mapOfSchemasChange, 5);\n\t\t\tAssert.AreEqual(mapOfNumbersChange, 5);\n\t\t\tAssert.AreEqual(mapOfStringsChange, 5);\n\t\t\tAssert.AreEqual(mapOfIntChange, 5);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MapSchemaInt8Test()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.MapSchemaInt8.MapSchemaInt8>();\n\t\t\tvar state = decoder.State;\n\t\t\tbyte[] bytes = { 128, 171, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 129, 1, 255, 1, 128, 0, 163, 98, 98, 98, 1, 128, 1, 163, 97, 97, 97, 1, 128, 2, 163, 50, 50, 49, 1, 128, 3, 163, 48, 50, 49, 1, 128, 4, 162, 49, 53, 1, 128, 5, 162, 49, 48, 1 };\n\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tAssert.AreEqual(state.status, \"Hello world\");\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"bbb\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"aaa\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"221\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"021\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"15\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"10\"], 1);\n\n\t\t\tbyte[] addBytes = { 255, 1, 0, 5, 2 };\n\t\t\tdecoder.Decode(addBytes);\n\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"bbb\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"aaa\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"221\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"021\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"15\"], 1);\n\t\t\tAssert.AreEqual(state.mapOfInt8[\"10\"], 2);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MapSchemaMoveNullifyTypeTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.MapSchemaMoveNullifyType.State>();\n\t\t\tvar state = decoder.State;\n\t\t\tbyte[] bytes = { 129, 1, 64, 255, 1, 128, 0, 161, 48, 0 };\n\n\t\t\tdecoder.Decode(bytes);\n\n\t\t\tAssert.DoesNotThrow(() =>\n\t\t\t{\n\t\t\t\t// FIXME: this test only passes because empty\n\t\t\t\tbyte[] moveAndNullifyBytes = { 128, 1, 65 };\n\t\t\t\tdecoder.Decode(moveAndNullifyBytes);\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InheritedTypesTest()\n\t\t{\n\t\t\tvar serializer = new Colyseus.SchemaSerializer<SchemaTest.InheritedTypes.InheritedTypes>();\n\t\t\tbyte[] handshake = { 128, 1, 255, 1, 128, 0, 2, 128, 1, 8, 128, 2, 12, 128, 3, 15, 255, 2, 130, 3, 128, 0, 255, 3, 128, 0, 4, 128, 1, 5, 128, 2, 6, 128, 3, 7, 255, 4, 128, 166, 101, 110, 116, 105, 116, 121, 130, 1, 129, 163, 114, 101, 102, 255, 5, 128, 166, 112, 108, 97, 121, 101, 114, 130, 2, 129, 163, 114, 101, 102, 255, 6, 128, 163, 98, 111, 116, 130, 3, 129, 163, 114, 101, 102, 255, 7, 128, 163, 97, 110, 121, 130, 1, 129, 163, 114, 101, 102, 255, 8, 130, 9, 128, 1, 255, 9, 128, 0, 10, 128, 1, 11, 255, 10, 128, 161, 120, 129, 166, 110, 117, 109, 98, 101, 114, 255, 11, 128, 161, 121, 129, 166, 110, 117, 109, 98, 101, 114, 255, 12, 130, 13, 128, 2, 129, 1, 255, 13, 128, 0, 14, 255, 14, 128, 164, 110, 97, 109, 101, 129, 166, 115, 116, 114, 105, 110, 103, 255, 15, 130, 16, 128, 3, 129, 2, 255, 16, 128, 0, 17, 255, 17, 128, 165, 112, 111, 119, 101, 114, 129, 166, 110, 117, 109, 98, 101, 114 };\n\t\t\tserializer.Handshake(handshake, 0);\n\n\t\t\tbyte[] bytes = { 128, 1, 129, 2, 130, 3, 131, 4, 213, 3, 255, 1, 128, 205, 244, 1, 129, 205, 32, 3, 255, 2, 128, 204, 200, 129, 205, 44, 1, 130, 166, 80, 108, 97, 121, 101, 114, 255, 3, 128, 100, 129, 204, 150, 130, 163, 66, 111, 116, 131, 204, 200, 255, 4, 131, 100 };\n\t\t\tserializer.SetState(bytes);\n\n\t\t\tvar state = serializer.GetState();\n\n\t\t\tAssert.IsInstanceOf(typeof(SchemaTest.InheritedTypes.Entity), state.entity);\n\t\t\tAssert.AreEqual(state.entity.x, 500);\n\t\t\tAssert.AreEqual(state.entity.y, 800);\n\n\t\t\tAssert.IsInstanceOf(typeof(SchemaTest.InheritedTypes.Player), state.player);\n\t\t\tAssert.AreEqual(state.player.x, 200);\n\t\t\tAssert.AreEqual(state.player.y, 300);\n\t\t\tAssert.AreEqual(state.player.name, \"Player\");\n\n\t\t\tAssert.IsInstanceOf(typeof(SchemaTest.InheritedTypes.Bot), state.bot);\n\t\t\tAssert.AreEqual(state.bot.x, 100);\n\t\t\tAssert.AreEqual(state.bot.y, 150);\n\t\t\tAssert.AreEqual(state.bot.name, \"Bot\");\n\t\t\tAssert.AreEqual(state.bot.power, 200);\n\n\t\t\tAssert.IsInstanceOf(typeof(SchemaTest.InheritedTypes.Bot), state.any);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BackwardsForwardsTest()\n\t\t{\n\t\t\tbyte[] statev1bytes = { 129, 1, 128, 171, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 255, 1, 128, 0, 163, 111, 110, 101, 2, 255, 2, 128, 203, 232, 229, 22, 37, 231, 231, 209, 63, 129, 203, 240, 138, 15, 5, 219, 40, 223, 63 };\n\t\t\tbyte[] statev2bytes = { 128, 171, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 130, 10 };\n\n\t\t\tvar v2decoder = new Colyseus.Schema.Decoder<SchemaTest.BackwardsForwards.StateV2>();\n\t\t\tvar statev2 = v2decoder.State;\n\t\t\tv2decoder.Decode(statev1bytes);\n\t\t\tAssert.AreEqual(statev2.str, \"Hello world\");\n\n\t\t\tvar v1decoder = new Colyseus.Schema.Decoder<SchemaTest.BackwardsForwards.StateV1>();\n\t\t\tvar statev1 = v1decoder.State;\n\t\t\tv1decoder.Decode(statev2bytes);\n\t\t\tAssert.AreEqual(statev1.str, \"Hello world\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void FilteredTypesTest()\n\t\t{\n\t\t\t// var client1 = new SchemaTest.FilteredTypes.State();\n\t\t\t// client1.Decode(new byte[] { 255, 0, 130, 1, 128, 2, 128, 2, 255, 1, 128, 0, 4, 255, 2, 128, 163, 111, 110, 101, 255, 2, 128, 163, 111, 110, 101, 255, 4, 128, 163, 111, 110, 101 });\n\t\t\t// Assert.AreEqual(\"one\", client1.playerOne.name);\n\t\t\t// Assert.AreEqual(\"one\", client1.players[0].name);\n\t\t\t// Assert.AreEqual(null, client1.playerTwo.name);\n\n\t\t\t// var client2 = new SchemaTest.FilteredTypes.State();\n\t\t\t// client2.Decode(new byte[] { 255, 0, 130, 1, 129, 3, 129, 3, 255, 1, 128, 1, 5, 255, 3, 128, 163, 116, 119, 111, 255, 3, 128, 163, 116, 119, 111, 255, 5, 128, 163, 116, 119, 111 });\n\t\t\t// Assert.AreEqual(\"two\", client2.playerTwo.name);\n\t\t\t// Assert.AreEqual(\"two\", client2.players[0].name);\n\t\t\t// Assert.AreEqual(null, client2.playerOne.name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InstanceSharingTypesTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.InstanceSharingTypes.State>();\n\t\t\tvar refs = decoder.Refs;\n\t\t\tvar state = decoder.State;\n\n\t\t\tdecoder.Decode(new byte[]  { 130, 1, 131, 2, 128, 3, 129, 3, 255, 1, 255, 2, 255, 3, 128, 4, 255, 4, 128, 10, 129, 10 });\n\t\t\tAssert.AreEqual(state.player1, state.player2);\n\t\t\tAssert.AreEqual(state.player1.position, state.player2.position);\n\t\t\tAssert.AreEqual(refs.refCounts[state.player1.__refId], 2);\n\t\t\tAssert.AreEqual(5, refs.refs.Count);\n\n\t\t\tdecoder.Decode(new byte[] { 64, 65 });\n\t\t\tAssert.AreEqual(null, state.player2);\n\t\t\tAssert.AreEqual(null, state.player2);\n\t\t\tAssert.AreEqual(3, refs.refs.Count);\n\n\t\t\tdecoder.Decode(new byte[] { 255, 1, 128, 0, 5, 128, 1, 5, 128, 2, 5, 128, 3, 7, 255, 5, 128, 6, 255, 6, 128, 10, 129, 10, 255, 7, 128, 8, 255, 8, 128, 10, 129, 10 });\n\t\t\tAssert.AreEqual(state.arrayOfPlayers[0], state.arrayOfPlayers[1]);\n\t\t\tAssert.AreEqual(state.arrayOfPlayers[1], state.arrayOfPlayers[2]);\n\t\t\tAssert.AreNotEqual(state.arrayOfPlayers[2], state.arrayOfPlayers[3]);\n\t\t\tAssert.AreEqual(7, refs.refs.Count);\n\n\t\t\tdecoder.Decode(new byte[] { 255, 1, 64, 3, 64, 2, 64, 1 });\n\t\t\tAssert.AreEqual(1, state.arrayOfPlayers.Count);\n\t\t\tAssert.AreEqual(5, refs.refs.Count);\n\t\t\tvar previousArraySchemaRefId = state.arrayOfPlayers.__refId;\n\n\t\t\t// Replacing ArraySchema\n\t\t\tdecoder.Decode(new byte[] { 194, 9, 255, 9, 128, 0, 10, 255, 10, 128, 11, 255, 11, 128, 10, 129, 20 });\n\t\t\tAssert.AreEqual(false, refs.refs.ContainsKey(previousArraySchemaRefId));\n\t\t\tAssert.AreEqual(1, state.arrayOfPlayers.Count);\n\t\t\tAssert.AreEqual(5, refs.refs.Count);\n\n\t\t\t// Clearing ArraySchema\n\t\t\tdecoder.Decode(new byte[] { 255, 9, 10 });\n\t\t\tAssert.AreEqual(0, state.arrayOfPlayers.Count);\n\t\t\tAssert.AreEqual(3, refs.refs.Count);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CallbacksTest()\n\t\t{\n\t\t\tvar decoder = new Colyseus.Schema.Decoder<SchemaTest.Callbacks.CallbacksState>();\n\t\t\tvar state = decoder.State;\n\t\t\tvar callbacks = Colyseus.Schema.Callbacks.Get(decoder);\n\n\t\t\tvar onListenContainer = 0;\n\t\t\tvar onPlayerAdd = 0;\n\t\t\tvar onPlayerChange = 0;\n\t\t\tvar onPlayerRemove = 0;\n\n\t\t\tvar onItemAdd = 0;\n\t\t\tvar onItemChange = 0;\n\t\t\tvar onItemRemove = 0;\n\n\t\t\tcallbacks.Listen(state => state.container, (container, _) =>\n\t\t\t{\n\t\t\t\tonListenContainer++;\n\n\t\t\t\tcallbacks.OnAdd(container, container => container.playersMap, (sessionId, player) =>\n\t\t\t\t{\n\t\t\t\t\tonPlayerAdd++;\n\n\t\t\t\t\tcallbacks.OnAdd(player, player => player.items, (key, item) =>\n\t\t\t\t\t{\n\t\t\t\t\t\tonItemAdd++;\n\t\t\t\t\t});\n\n\t\t\t\t\tcallbacks.OnChange(player, player => player.items, (key, item) =>\n\t\t\t\t\t{\n\t\t\t\t\t\tonItemChange++;\n\t\t\t\t\t});\n\n\t\t\t\t\tcallbacks.OnRemove(player, player => player.items, (key, item) =>\n\t\t\t\t\t{\n\t\t\t\t\t\tonItemRemove++;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tcallbacks.OnChange(container, container => container.playersMap, (sessionId, player) =>\n\t\t\t\t{\n\t\t\t\t\tonPlayerChange++;\n\t\t\t\t});\n\n\t\t\t\tcallbacks.OnRemove(container, container => container.playersMap, (sessionId, player) =>\n\t\t\t\t{\n\t\t\t\t\tonPlayerRemove++;\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// (initial)\n\t\t\tdecoder.Decode(new byte[] { 128, 1, 255, 1, 128, 2, 255, 2 });\n\n\t\t\t// (1st encode)\n\t\t\tdecoder.Decode(new byte[] { 255, 1, 255, 2, 128, 0, 163, 111, 110, 101, 3, 128, 1, 163, 116, 119, 111, 9, 255, 2, 255, 3, 128, 4, 129, 5, 255, 4, 128, 1, 129, 2, 130, 3, 255, 5, 128, 0, 166, 105, 116, 101, 109, 45, 49, 6, 128, 1, 166, 105, 116, 101, 109, 45, 50, 7, 128, 2, 166, 105, 116, 101, 109, 45, 51, 8, 255, 6, 128, 166, 73, 116, 101, 109, 32, 49, 129, 1, 255, 7, 128, 166, 73, 116, 101, 109, 32, 50, 129, 2, 255, 8, 128, 166, 73, 116, 101, 109, 32, 51, 129, 3, 255, 9, 128, 10, 129, 11, 255, 10, 128, 1, 129, 2, 130, 3, 255, 11, 128, 0, 166, 105, 116, 101, 109, 45, 49, 12, 128, 1, 166, 105, 116, 101, 109, 45, 50, 13, 128, 2, 166, 105, 116, 101, 109, 45, 51, 14, 255, 12, 128, 166, 73, 116, 101, 109, 32, 49, 129, 1, 255, 13, 128, 166, 73, 116, 101, 109, 32, 50, 129, 2, 255, 14, 128, 166, 73, 116, 101, 109, 32, 51, 129, 3 });\n\n\t\t\tAssert.AreEqual(1, onListenContainer);\n\t\t\tAssert.AreEqual(2, onPlayerAdd);\n\t\t\tAssert.AreEqual(2, onPlayerChange);\n\t\t\tAssert.AreEqual(6, onItemAdd);\n\t\t\tAssert.AreEqual(6, onItemChange);\n\n\t\t\t// (2nd encode)\n\t\t\tdecoder.Decode(new byte[] { 255, 1, 255, 2, 64, 1, 128, 2, 165, 116, 104, 114, 101, 101, 16, 255, 2, 255, 3, 255, 4, 255, 5, 64, 0, 64, 1, 128, 3, 166, 105, 116, 101, 109, 45, 52, 15, 255, 8, 255, 5, 255, 5, 255, 15, 128, 166, 73, 116, 101, 109, 32, 52, 129, 4, 255, 2, 255, 16, 128, 17, 129, 18, 255, 17, 128, 1, 129, 2, 130, 3, 255, 18, 128, 0, 166, 105, 116, 101, 109, 45, 49, 19, 128, 1, 166, 105, 116, 101, 109, 45, 50, 20, 128, 2, 166, 105, 116, 101, 109, 45, 51, 21, 255, 19, 128, 166, 73, 116, 101, 109, 32, 49, 129, 1, 255, 20, 128, 166, 73, 116, 101, 109, 32, 50, 129, 2, 255, 21, 128, 166, 73, 116, 101, 109, 32, 51, 129, 3 });\n\n\t\t\t// (new container)\n\t\t\tdecoder.Decode(new byte[] { 128, 22, 255, 2, 255, 5, 255, 5, 255, 2, 255, 0, 255, 22, 128, 23, 255, 23, 128, 0, 164, 108, 97, 115, 116, 24, 255, 24, 128, 25, 129, 26, 255, 25, 128, 10, 129, 10, 130, 10, 255, 26, 128, 0, 163, 111, 110, 101, 27, 255, 27, 128, 166, 73, 116, 101, 109, 32, 49, 129, 1 });\n\n\t\t\tAssert.AreEqual(2, onListenContainer);\n\t\t\tAssert.AreEqual(4, onPlayerAdd);\n\t\t\tAssert.AreEqual(1, onPlayerRemove);\n\t\t\tAssert.AreEqual(5, onPlayerChange);\n\n\t\t\tAssert.AreEqual(11, onItemAdd);\n\t\t\tAssert.AreEqual(2, onItemRemove);\n\t\t\tAssert.AreEqual(13, onItemChange);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ReflectionDecodeTest()\n\t\t{\n\t\t\tbyte[] handshake = { 128, 1, 255, 1, 128, 0, 2, 128, 1, 8, 128, 2, 12, 128, 3, 15, 255, 2, 130, 3, 128, 0, 255, 3, 128, 0, 4, 128, 1, 5, 128, 2, 6, 128, 3, 7, 255, 4, 128, 166, 101, 110, 116, 105, 116, 121, 130, 1, 129, 163, 114, 101, 102, 255, 5, 128, 166, 112, 108, 97, 121, 101, 114, 130, 2, 129, 163, 114, 101, 102, 255, 6, 128, 163, 98, 111, 116, 130, 3, 129, 163, 114, 101, 102, 255, 7, 128, 163, 97, 110, 121, 130, 1, 129, 163, 114, 101, 102, 255, 8, 130, 9, 128, 1, 255, 9, 128, 0, 10, 128, 1, 11, 255, 10, 128, 161, 120, 129, 166, 110, 117, 109, 98, 101, 114, 255, 11, 128, 161, 121, 129, 166, 110, 117, 109, 98, 101, 114, 255, 12, 130, 13, 128, 2, 129, 1, 255, 13, 128, 0, 14, 255, 14, 128, 164, 110, 97, 109, 101, 129, 166, 115, 116, 114, 105, 110, 103, 255, 15, 130, 16, 128, 3, 129, 2, 255, 16, 128, 0, 17, 255, 17, 128, 165, 112, 111, 119, 101, 114, 129, 166, 110, 117, 109, 98, 101, 114 };\n\n\t\t\tvar it = new Iterator { Offset = 0 };\n\t\t\tvar reflectionDecoder = new Decoder<Reflection>();\n\t\t\treflectionDecoder.Decode(handshake, it);\n\n\t\t\tvar reflection = reflectionDecoder.State;\n\n\t\t\tAssert.IsNotNull(reflection.types, \"types should not be null\");\n\t\t\tAssert.Greater(reflection.types.Count, 0, \"types should have entries\");\n\t\t\tAssert.AreEqual(4, reflection.types.Count, $\"expected 4 types, rootType={reflection.rootType}\");\n\n\t\t\tfor (int i = 0; i < reflection.types.Count; i++)\n\t\t\t{\n\t\t\t\tvar t = reflection.types[i];\n\t\t\t\tAssert.IsNotNull(t.fields, $\"Type[{i}] id={t.id} should have fields\");\n\t\t\t}\n\t\t}\n\n\t}\n\n}\n"
  },
  {
    "path": "nuget/tests/SchemaDeserializerTest.cs.meta",
    "content": "fileFormatVersion: 2\nguid: ddcb67059f6353642b43a764acd9b4fc"
  },
  {
    "path": "nuget/tests/SerializationTest.cs",
    "content": "using NUnit.Framework;\nusing Colyseus;\n\nnamespace Colyseus.Tests\n{\n\n\t[TestFixture]\n\tpublic class SerializationTest\n\t{\n\n\t\t[Test]\n\t\tpublic void NoStateSerializerTest()\n\t\t{\n\t\t\tvar serializer = (ISerializer<NoState>)new NoneSerializer();\n\t\t\tAssert.AreEqual(true, serializer.GetState() is NoState);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "nuget/tests/SerializationTest.cs.meta",
    "content": "fileFormatVersion: 2\nguid: e8fcb142d5e2049488327be26fbf22bc"
  },
  {
    "path": "nuget/tests/WebSocketTransportTest.cs",
    "content": "#if !UNITY_EDITOR\n\nusing System;\nusing System.Threading;\nusing NUnit.Framework;\n\nnamespace Colyseus.Tests\n{\n    [TestFixture]\n    [NonParallelizable]\n    public class WebSocketTransportTest\n    {\n        private Action<NativeWebSocket.WebSocket> _previousRegister;\n        private Action<NativeWebSocket.WebSocket> _previousUnregister;\n\n        [SetUp]\n        public void SetUp()\n        {\n            _previousRegister = ColyseusContext.RegisterWebSocketForDispatch;\n            _previousUnregister = ColyseusContext.UnregisterWebSocketForDispatch;\n\n            ColyseusContext.RegisterWebSocketForDispatch = null;\n            ColyseusContext.UnregisterWebSocketForDispatch = null;\n        }\n\n        [TearDown]\n        public void TearDown()\n        {\n            ColyseusContext.RegisterWebSocketForDispatch = _previousRegister;\n            ColyseusContext.UnregisterWebSocketForDispatch = _previousUnregister;\n        }\n\n        [Test]\n        public void UsesSharedDispatchLoopWithoutContextOrExternalDispatcher()\n        {\n            Assert.IsTrue(WebSocketTransport.ShouldUseSharedDispatchLoop(null));\n        }\n\n        [Test]\n        public void SkipsSharedDispatchLoopWhenSynchronizationContextExists()\n        {\n            Assert.IsFalse(WebSocketTransport.ShouldUseSharedDispatchLoop(new SynchronizationContext()));\n        }\n\n        [Test]\n        public void SkipsSharedDispatchLoopWhenExternalDispatcherExists()\n        {\n            ColyseusContext.RegisterWebSocketForDispatch = _ => { };\n\n            Assert.IsFalse(WebSocketTransport.ShouldUseSharedDispatchLoop(null));\n        }\n    }\n}\n\n#endif"
  },
  {
    "path": "nuget-monogame/Colyseus.MonoGame.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net10.0</TargetFramework>\n    <LangVersion>9.0</LangVersion>\n    <AssemblyName>Colyseus.MonoGame</AssemblyName>\n    <RootNamespace>Colyseus.MonoGame</RootNamespace>\n    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>\n    <IsPackable>true</IsPackable>\n\n    <!-- NuGet package metadata -->\n    <PackageId>Colyseus.MonoGame</PackageId>\n    <Authors>Endel Dreyer</Authors>\n    <Description>MonoGame integration for Colyseus Multiplayer SDK — provides a GameComponent that dispatches WebSocket events on the game loop.</Description>\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\n    <PackageProjectUrl>https://colyseus.io/</PackageProjectUrl>\n    <RepositoryUrl>https://github.com/colyseus/colyseus-unity-sdk</RepositoryUrl>\n    <PackageTags>colyseus;multiplayer;networking;monogame;gamedev</PackageTags>\n    <PackageReadmeFile>README.md</PackageReadmeFile>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <None Include=\"README.md\" Pack=\"true\" PackagePath=\"\\\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Colyseus\" Version=\"[0.17,0.18)\" />\n    <PackageReference Include=\"Colyseus.NativeWebSocket\" Version=\"2.0.0\" />\n    <PackageReference Include=\"MonoGame.Framework.DesktopGL\" Version=\"3.8.2.1105\" />\n  </ItemGroup>\n\n  <!-- Read version from UPM package.json -->\n  <Target Name=\"SetVersionFromPackageJson\" BeforeTargets=\"PrepareForBuild;GenerateNuspec\">\n    <Exec Command=\"python3 -c &quot;import json; print(json.load(open('$(MSBuildProjectDirectory)/../Assets/Colyseus/package.json'))['version'])&quot;\" ConsoleToMSBuild=\"true\">\n      <Output TaskParameter=\"ConsoleOutput\" PropertyName=\"PackageVersion\" />\n    </Exec>\n  </Target>\n\n</Project>\n"
  },
  {
    "path": "nuget-monogame/ColyseusGameComponent.cs",
    "content": "using System.Collections.Generic;\nusing Microsoft.Xna.Framework;\n\nnamespace Colyseus.MonoGame\n{\n    public class ColyseusGameComponent : GameComponent\n    {\n        private readonly List<NativeWebSocket.WebSocket> _sockets = new List<NativeWebSocket.WebSocket>();\n\n        public ColyseusGameComponent(Game game) : base(game)\n        {\n            ColyseusContext.RegisterWebSocketForDispatch = (ws) =>\n            {\n                lock (_sockets) { _sockets.Add(ws); }\n            };\n            ColyseusContext.UnregisterWebSocketForDispatch = (ws) =>\n            {\n                lock (_sockets) { _sockets.Remove(ws); }\n            };\n        }\n\n        public override void Update(GameTime gameTime)\n        {\n            lock (_sockets)\n            {\n                for (var i = 0; i < _sockets.Count; i++)\n                {\n                    _sockets[i].DispatchMessageQueue();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "nuget-monogame/README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://colyseus.io/\">\n    <img src=\"https://github.com/colyseus/colyseus/blob/master/media/logo.svg?raw=true\" width=\"40%\" />\n  </a>\n  <h3>Colyseus Multiplayer SDK for MonoGame</h3>\n</div>\n\nMonoGame integration for [Colyseus](https://colyseus.io/) — provides a `GameComponent` that automatically dispatches WebSocket events on the game loop.\n\n## Installation\n\n```sh\ndotnet add package Colyseus.MonoGame\n```\n\nThis installs the core `Colyseus` SDK as a dependency.\n\n## Setup\n\nRegister the `ColyseusGameComponent` in your game's `Initialize()` method:\n\n```csharp\nusing Colyseus.MonoGame;\n\nprotected override void Initialize()\n{\n    Components.Add(new ColyseusGameComponent(this));\n    base.Initialize();\n}\n```\n\nThis single line handles all WebSocket event dispatching on the game thread — no manual polling needed.\n\n## Quick Example\n\n```csharp\nusing Microsoft.Xna.Framework;\nusing Colyseus;\nusing Colyseus.Schema;\nusing Colyseus.MonoGame;\n\npublic class Game1 : Game\n{\n    Client client;\n    Room<MyRoomState> room;\n\n    protected override void Initialize()\n    {\n        Components.Add(new ColyseusGameComponent(this));\n        base.Initialize();\n    }\n\n    protected override async void LoadContent()\n    {\n        client = new Client(\"ws://localhost:2567\");\n\n        room = await client.JoinOrCreate<MyRoomState>(\"my_room\");\n\n        var callbacks = Callbacks.Get(room);\n\n        callbacks.OnAdd(state => state.players, (sessionId, player) => {\n            System.Diagnostics.Debug.WriteLine($\"Player joined: {sessionId}\");\n        });\n\n        room.Send(\"move\", new { x = 10f, y = 20f });\n\n        room.OnMessage<string>(\"chat\", (message) => {\n            System.Diagnostics.Debug.WriteLine(\"Chat: \" + message);\n        });\n    }\n\n    protected override void OnExiting(object sender, EventArgs args)\n    {\n        if (room != null) room.Leave();\n        base.OnExiting(sender, args);\n    }\n}\n```\n\n## Documentation\n\nSee the full documentation at **https://docs.colyseus.io/getting-started/monogame**\n\n## License\n\nMIT\n"
  },
  {
    "path": "unity-setup.sh",
    "content": "#!/bin/bash\nset -e\n\nNATIVEWEBSOCKET_BRANCH=\"upm-2\"\nNATIVEWEBSOCKET_REPO=\"https://github.com/endel/NativeWebSocket.git\"\nNATIVEWEBSOCKET_DIR=\"Assets/Colyseus/Runtime/WebSocket\"\n\nTMPDIR=$(mktemp -d)\ntrap \"rm -rf $TMPDIR\" EXIT\n\ngit clone --branch \"$NATIVEWEBSOCKET_BRANCH\" --depth 1 \"$NATIVEWEBSOCKET_REPO\" \"$TMPDIR\"\n\nrm -rf \"$NATIVEWEBSOCKET_DIR\"\ncp -r \"$TMPDIR/WebSocket\" \"$NATIVEWEBSOCKET_DIR\"\n"
  }
]