├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── jswebrtcnetwork ├── Gruntfile.js ├── karma.conf.js ├── nbproject │ ├── .gitignore │ ├── licenseheader.txt │ ├── project.properties │ └── project.xml ├── package.json ├── src │ ├── FirebaseSignalingChan.js │ ├── InterfaceSignalingChan.js │ ├── JSONConnectorProtocol.js │ ├── LocalSignalingChan.js │ ├── SocketIoSignalingChan.js │ ├── examples │ │ ├── test.html │ │ ├── testWebRtc.html │ │ ├── testWebRtcClient.html │ │ └── testWebRtcServer.html │ └── webrtcnetwork.js └── test │ ├── helpers.js │ ├── readme karma.txt │ ├── test.txt │ └── unit │ ├── CAPIWebRtcNetworkTest.js │ ├── FirebaseSignalingTest.js │ ├── JSONConnectorProtocolTest.js │ ├── LocalSignalingTest.js │ ├── LocalWebRTCTest.js │ ├── WebRtcClientServerTest.js │ └── WebRtcNetworkTest.js ├── socketiosignalingserver ├── package.json ├── public │ ├── SocketIoSignalingChan.js │ └── index.html └── server.js └── unitywebrtc ├── .gitignore ├── Assets ├── WebGLTemplates │ ├── LICENSE │ └── WebRtcNetwork │ │ ├── TemplateData │ │ ├── UnityProgress.js │ │ ├── default-cover.jpg │ │ ├── favicon.ico │ │ ├── fullbar.png │ │ ├── fullscreen.png │ │ ├── loadingbar.png │ │ ├── logo.png │ │ ├── progresslogo.png │ │ └── style.css │ │ ├── index.html │ │ └── webrtcnetworkplugin.js └── WebRtcNetwork │ ├── LICENSE │ ├── Plugins │ └── WebGL │ │ └── WebRtcNetwork.jslib │ ├── Resources │ └── webrtcnetworkplugin.txt │ ├── ULib │ ├── Net │ │ ├── ByteArrayBuffer.cs │ │ ├── ConnectionId.cs │ │ ├── IBasicNetwork.cs │ │ ├── MessageDataBuffer.cs │ │ ├── NetworkEvent.cs │ │ ├── SingleEndpointConnection.cs │ │ ├── UnityNetwork.cs │ │ └── WebRtcNetwork.cs │ └── Tools │ │ └── DebugHelper.cs │ ├── example │ ├── ChatApp.cs │ ├── LocalTest.cs │ ├── MenuScene.cs │ ├── MessageList.cs │ ├── Text.prefab │ ├── chatscene.unity │ └── menuscene.unity │ └── readme.txt ├── LICENSE └── ProjectSettings ├── AudioManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityAdsSettings.asset └── UnityAnalyticsManager.asset /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | x64/ 14 | build/ 15 | bld/ 16 | [Bb]in/ 17 | [Oo]bj/ 18 | 19 | # Roslyn cache directories 20 | *.ide/ 21 | 22 | # MSTest test Results 23 | [Tt]est[Rr]esult*/ 24 | [Bb]uild[Ll]og.* 25 | 26 | #NUNIT 27 | *.VisualState.xml 28 | TestResult.xml 29 | 30 | # Build Results of an ATL Project 31 | [Dd]ebugPS/ 32 | [Rr]eleasePS/ 33 | dlldata.c 34 | 35 | *_i.c 36 | *_p.c 37 | *_i.h 38 | *.ilk 39 | *.meta 40 | *.obj 41 | *.pch 42 | *.pdb 43 | *.pgc 44 | *.pgd 45 | *.rsp 46 | *.sbr 47 | *.tlb 48 | *.tli 49 | *.tlh 50 | *.tmp 51 | *.tmp_proj 52 | *.log 53 | *.vspscc 54 | *.vssscc 55 | .builds 56 | *.pidb 57 | *.svclog 58 | *.scc 59 | 60 | # Chutzpah Test files 61 | _Chutzpah* 62 | 63 | # Visual C++ cache files 64 | ipch/ 65 | *.aps 66 | *.ncb 67 | *.opensdf 68 | *.sdf 69 | *.cachefile 70 | 71 | # Visual Studio profiler 72 | *.psess 73 | *.vsp 74 | *.vspx 75 | 76 | # TFS 2012 Local Workspace 77 | $tf/ 78 | 79 | # Guidance Automation Toolkit 80 | *.gpState 81 | 82 | # ReSharper is a .NET coding add-in 83 | _ReSharper*/ 84 | *.[Rr]e[Ss]harper 85 | *.DotSettings.user 86 | 87 | # JustCode is a .NET coding addin-in 88 | .JustCode 89 | 90 | # TeamCity is a build add-in 91 | _TeamCity* 92 | 93 | # DotCover is a Code Coverage Tool 94 | *.dotCover 95 | 96 | # NCrunch 97 | _NCrunch_* 98 | .*crunch*.local.xml 99 | 100 | # MightyMoose 101 | *.mm.* 102 | AutoTest.Net/ 103 | 104 | # Web workbench (sass) 105 | .sass-cache/ 106 | 107 | # Installshield output folder 108 | [Ee]xpress/ 109 | 110 | # DocProject is a documentation generator add-in 111 | DocProject/buildhelp/ 112 | DocProject/Help/*.HxT 113 | DocProject/Help/*.HxC 114 | DocProject/Help/*.hhc 115 | DocProject/Help/*.hhk 116 | DocProject/Help/*.hhp 117 | DocProject/Help/Html2 118 | DocProject/Help/html 119 | 120 | # Click-Once directory 121 | publish/ 122 | 123 | # Publish Web Output 124 | *.[Pp]ublish.xml 125 | *.azurePubxml 126 | ## TODO: Comment the next line if you want to checkin your 127 | ## web deploy settings but do note that will include unencrypted 128 | ## passwords 129 | #*.pubxml 130 | 131 | # NuGet Packages Directory 132 | packages/* 133 | ## TODO: If the tool you use requires repositories.config 134 | ## uncomment the next line 135 | #!packages/repositories.config 136 | 137 | # Enable "build/" folder in the NuGet Packages folder since 138 | # NuGet packages use it for MSBuild targets. 139 | # This line needs to be after the ignore of the build folder 140 | # (and the packages folder if the line above has been uncommented) 141 | !packages/build/ 142 | 143 | # Windows Azure Build Output 144 | csx/ 145 | *.build.csdef 146 | 147 | # Windows Store app package directory 148 | AppPackages/ 149 | 150 | # Others 151 | sql/ 152 | *.Cache 153 | ClientBin/ 154 | [Ss]tyle[Cc]op.* 155 | ~$* 156 | *~ 157 | *.dbmdl 158 | *.dbproj.schemaview 159 | *.pfx 160 | *.publishsettings 161 | node_modules/ 162 | 163 | # RIA/Silverlight projects 164 | Generated_Code/ 165 | 166 | # Backup & report files from converting an old project file 167 | # to a newer Visual Studio version. Backup files are not needed, 168 | # because we have git ;-) 169 | _UpgradeReport_Files/ 170 | Backup*/ 171 | UpgradeLog*.XML 172 | UpgradeLog*.htm 173 | 174 | # SQL Server files 175 | *.mdf 176 | *.ldf 177 | 178 | # Business Intelligence projects 179 | *.rdl.data 180 | *.bim.layout 181 | *.bim_*.settings 182 | 183 | # Microsoft Fakes 184 | FakesAssemblies/ 185 | 186 | # LightSwitch generated files 187 | GeneratedArtifacts/ 188 | _Pvt_Extensions/ 189 | ModelManifest.xml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Christoph Kutza 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Note: This is the old java script version of WebRtcNetwork. It is now under the MIT license so you can use it 2 | any way you want! 3 | 4 | The Unity Asset WebRtcNetwork switched to a complete new rewritten type script library. 5 | (will be published on github in the future) 6 | 7 | # WebRTCNetwork 8 | A simple and well defined API to access WebRTC DataChannels from Unity or Emscripten 9 | 10 | ## for Unity 11 | 12 | The unity version is contained in an example project (folder unitywebrtc). Simply open the project in Unity 13 | and build the WebGL version. It should run without any additional changes. 14 | 15 | ### WebRtcNetwork 16 | 17 | This is the main class of the system. It allows you to start a allow incomming connections 18 | or connect to another system. 19 | The connections are unlike websockets direct connections. It allows tcp style ordered, reliable 20 | data transfer or udp style unordered, unreliable messages. 21 | 22 | The way a connection is etablished is rather different from other libraries due to the structure 23 | of WebRTC. While TCP and UDP use the IP address+port to connect directly, WebRTC needs a 24 | custom signaling server that delegates the etablishment between two systems. Handling 25 | of ip addresses, ports and NAT traversal is all done automatically. 26 | 27 | The example uses a test signaling server so it should work immediately. You can setup 28 | your own signaling server using a socket.io server (code in socketiosignalingserver) 29 | or a firebase account (free for 30CCU) 30 | 31 | Note: As WebRTC is a browser functionality the WebRtc class won't work in the Unity Editor or 32 | any other build. See UnityNetwork 33 | 34 | ### UnityNetwork 35 | 36 | Unity Network is a helper class that allows you to similate the behaviour of WebRTCNetwork in 37 | Unity Editor or builds that support unity network. It won't work while set up for "WebGL" though! 38 | Make sure it isn't set in the build settings! 39 | The chat example shows how you can use this class to test your network code locally. I would not 40 | recomment using this class in any release builds as it might not be unstable. 41 | Also note that unity network doesn't support multiple servers/connections at the same time thus 42 | you can only create one single instance and only start a server or connect to a single server. It 43 | also doesn't support connection via a choosen name. After creating a server the ServerInitialzied 44 | event will return a randomly choosen number that can be used to connect. 45 | -------------------------------------------------------------------------------- /jswebrtcnetwork/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * Is suppose to minifi all related files except external files like 5 | * firebase.js, clean build dir, and copy everything in the build dir 6 | * 7 | * + a release mod that copys everything into unitys template dir 8 | * 9 | * -> after that unity finishes the rest 10 | */ 11 | module.exports = function(grunt) { 12 | 13 | // Project configuration. 14 | grunt.initConfig({ 15 | pkg: grunt.file.readJSON('package.json'), 16 | copy:{ 17 | build:{ 18 | cwd:'src', 19 | src:['**'], 20 | dest:'build', 21 | expand:true 22 | }, 23 | toUnityTemplate:{ 24 | src:'build/webrtcnetworkplugin.js', 25 | dest:'../unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/webrtcnetworkplugin.js' 26 | }, 27 | toUnityResource:{ 28 | src:'build/webrtcnetworkplugin.js', 29 | dest:'../unitywebrtc/Assets/WebRtcNetwork/Resources/webrtcnetworkplugin.txt' 30 | } 31 | }, 32 | clean:{ 33 | build:{ 34 | src:'build' 35 | } 36 | }, 37 | uglify: { 38 | options: { 39 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n', 40 | mangle: false 41 | }, 42 | build: { 43 | src: 'src/*.js', 44 | dest: 'build/webrtcnetworkplugin.js' 45 | } 46 | }, 47 | karma: { 48 | unit: { 49 | configFile: 'karma.conf.js' 50 | } 51 | } 52 | }); 53 | 54 | // Load the plugin that provides the "uglify" task. 55 | grunt.loadNpmTasks('grunt-contrib-uglify'); 56 | grunt.loadNpmTasks('grunt-contrib-copy'); 57 | grunt.loadNpmTasks('grunt-contrib-clean'); 58 | 59 | grunt.registerTask( 60 | 'build', 61 | 'Compiles all the assets and copies the files to the build directory.', 62 | [ 'clean', 'uglify', 'copy' ] 63 | ); 64 | 65 | // Default task(s). 66 | grunt.registerTask('default', ['copy']); 67 | // Default task(s). 68 | grunt.registerTask('ToUnity', ['uglify']); 69 | grunt.registerTask('karma', ['karma']); 70 | }; -------------------------------------------------------------------------------- /jswebrtcnetwork/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Wed Sep 30 2015 13:00:22 GMT+1300 (New Zealand Daylight Time) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | files: [ 18 | 'test/**/*.js', 'src/*.js', 'https://cdn.firebase.com/js/client/2.3.0/firebase.js' 19 | 20 | //'test/helpers.js', 'test/unit/FirebaseSignalingTest.js', 'src/*.js', 'https://cdn.firebase.com/js/client/2.3.0/firebase.js' 21 | ], 22 | 23 | 24 | // list of files to exclude 25 | exclude: [ 26 | ], 27 | 28 | 29 | // preprocess matching files before serving them to the browser 30 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 31 | preprocessors: { 32 | }, 33 | 34 | 35 | // test results reporter to use 36 | // possible values: 'dots', 'progress' 37 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 38 | reporters: ['progress'], 39 | 40 | 41 | // web server port 42 | port: 9876, 43 | 44 | 45 | // enable / disable colors in the output (reporters and logs) 46 | colors: true, 47 | 48 | 49 | // level of logging 50 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 51 | logLevel: config.LOG_INFO, 52 | 53 | 54 | // enable / disable watching file and executing tests whenever any file changes 55 | autoWatch: true, 56 | 57 | 58 | // start these browsers 59 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 60 | browsers: ['Chrome'], 61 | 62 | 63 | // Continuous Integration mode 64 | // if true, Karma captures browsers, runs the tests and exits 65 | singleRun: false 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /jswebrtcnetwork/nbproject/.gitignore: -------------------------------------------------------------------------------- 1 | /private 2 | -------------------------------------------------------------------------------- /jswebrtcnetwork/nbproject/licenseheader.txt: -------------------------------------------------------------------------------- 1 | <#if licenseFirst??> 2 | ${licenseFirst} 3 | 4 | ${licensePrefix}Copyright (C) 2015 Christoph Kutza 5 | ${licensePrefix} 6 | ${licensePrefix}Please refer to the LICENSE file for license information 7 | <#if licenseLast??> 8 | ${licenseLast} 9 | -------------------------------------------------------------------------------- /jswebrtcnetwork/nbproject/project.properties: -------------------------------------------------------------------------------- 1 | auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options= 2 | auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false 3 | auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css 4 | auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options= 5 | auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false 6 | auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css 7 | auxiliary.org-netbeans-modules-javascript2-requirejs.enabled=false 8 | auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs 9 | browser.autorefresh.Chrome.INTEGRATED=true 10 | browser.highlightselection.Chrome.INTEGRATED=true 11 | file.reference.jsunitywebrtc-public_html=public_html 12 | file.reference.jsunitywebrtc-src=src 13 | file.reference.jsunitywebrtc-test=test 14 | file.reference.webrtcnetwork-public_html=public_html 15 | file.reference.webrtcnetwork-test=test 16 | files.encoding=UTF-8 17 | grunt.action.build=build 18 | grunt.action.clean=clean 19 | grunt.action.rebuild=clean build 20 | project.license=gpl30 21 | project.licensePath=./nbproject/licenseheader.txt 22 | site.root.folder=${file.reference.jsunitywebrtc-src} 23 | start.file=examples/test.html 24 | test.folder=${file.reference.jsunitywebrtc-test} 25 | web.context.root=/webrtcnetwork 26 | -------------------------------------------------------------------------------- /jswebrtcnetwork/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.web.clientproject 4 | 5 | 6 | unitywebrtc 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /jswebrtcnetwork/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unitywebrtc", 3 | "version": "0.1.0", 4 | "devDependencies": { 5 | "grunt": "~0.4.5", 6 | "grunt-contrib-clean": "0.4.x", 7 | "grunt-contrib-copy": "0.4.x", 8 | "grunt-contrib-jshint": "~0.10.0", 9 | "grunt-contrib-nodeunit": "~0.4.1", 10 | "grunt-contrib-uglify": "~0.5.0", 11 | "grunt-karma": "^0.12.1", 12 | "jasmine-core": "^2.3.4", 13 | "karma": "^0.13.10", 14 | "karma-chrome-launcher": "^0.2.0", 15 | "karma-cli": "^0.1.1", 16 | "karma-jasmine": "^0.3.6", 17 | "karma-phantomjs-launcher": "^0.2.1", 18 | "phantomjs": "^1.9.18" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jswebrtcnetwork/src/FirebaseSignalingChan.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | /**Allows the use of a Firebase account as signaling channel. 7 | * 8 | * @param {type} lUrl your firebase account URL e.g. https://incandescent-inferno-5269.firebaseio.com/webrtcnetwork0_9/ 9 | * 10 | */ 11 | function FirebaseSignalingChan(lUrl) 12 | { 13 | var mHandler; 14 | 15 | var mIsRoomOwner = false; 16 | var mConnecting = false; 17 | var mRunning = false; 18 | 19 | var mTimeout = 10000; 20 | var mConnectTimeoutId = null; 21 | var mCleanupTimer = null; 22 | var mFirebase = null; 23 | 24 | 25 | var mUrl = 'https://incandescent-inferno-5269.firebaseio.com/webrtcnetwork0_9/'; 26 | if(lUrl != null) 27 | mUrl = lUrl; 28 | 29 | /**Opens a new room. Result will be: 30 | * * SignalingMessageType.Connected if the room is opened 31 | * * SignalingMessageType.Closed if the room is already opened 32 | * 33 | * @param {type} lName 34 | * @param {type} lHandler a function(SignalingMessageType, messageContent(string)); 35 | * @returns {undefined} 36 | */ 37 | this.Open = function(lName, lHandler) 38 | { 39 | mHandler = lHandler; 40 | mIsRoomOwner = true; 41 | mConnecting = true; 42 | StartFirebase(lName); 43 | mFirebase.onDisconnect().remove(); 44 | }; 45 | 46 | function StartConnectTimeout() 47 | { 48 | mConnectTimeoutId = setTimeout(function() 49 | { 50 | if(mConnecting) 51 | { 52 | mConnecting = false; 53 | mFirebase.off('value', RecMessage); 54 | mFirebase.off('child_added', RecMessage); 55 | mFirebase = null; 56 | mHandler(SignalingMessageType.Closed, null); 57 | } 58 | mConnectTimeoutId = null; 59 | }, mTimeout); 60 | } 61 | function ClearConnectTimeout() 62 | { 63 | clearTimeout(mConnectTimeoutId); 64 | mConnectTimeoutId = null; 65 | } 66 | function StartFirebase(lName) 67 | { 68 | mFirebase = new Firebase(mUrl + lName); 69 | mFirebase.channel = lName; 70 | mFirebase.on('value', RecValue); 71 | 72 | //just in case. the value handler can be called during the on call and close the channel immediately 73 | if(mFirebase != null) 74 | mFirebase.on('child_added', RecMessage); 75 | StartConnectTimeout(); 76 | } 77 | 78 | /**Same as open but it only connects to an existing room 79 | * 80 | * @param {type} lName 81 | * @param {type} lHandler 82 | * @returns {undefined} 83 | */ 84 | this.Connect = function(lName, lHandler) 85 | { 86 | mHandler = lHandler; 87 | mIsRoomOwner = false; 88 | mConnecting = true; 89 | StartFirebase(lName); 90 | //mFirebase.onDisconnect().remove(); 91 | }; 92 | 93 | function DeleteMessageLog() 94 | { 95 | mFirebase.set('{o:open}'); 96 | } 97 | function RecValue(lFirebaseMsg) 98 | { 99 | var lMsg = lFirebaseMsg.val(); 100 | 101 | if(mConnecting && mIsRoomOwner) 102 | { 103 | mConnecting = false; 104 | ClearConnectTimeout(); 105 | if(lMsg == null) 106 | { 107 | mRunning = true; 108 | //nothing stored means -> room was just opened 109 | mHandler(SignalingMessageType.Connected, null); 110 | //set random content that isn't a message so others see its opened 111 | DeleteMessageLog(); 112 | }else 113 | { 114 | //something is already stored at this address -> room already in use 115 | mHandler(SignalingMessageType.Closed, null); 116 | } 117 | }else if(mConnecting && mIsRoomOwner === false) 118 | { 119 | mConnecting = false; 120 | ClearConnectTimeout(); 121 | if(lMsg != null) 122 | { 123 | mRunning = true; 124 | //room is open -> connect 125 | mHandler(SignalingMessageType.Connected, null); 126 | }else 127 | { 128 | 129 | //nothing stored means -> room was just opened 130 | mHandler(SignalingMessageType.Closed, null); 131 | } 132 | }else if(mRunning && mIsRoomOwner === false && lMsg == null) 133 | { 134 | //client side just noticed that the server shut down (all data deleted) 135 | 136 | mHandler(SignalingMessageType.Closed, null); 137 | } 138 | } 139 | 140 | function RecMessage(lFirebaseMsg) 141 | { 142 | if(mIsRoomOwner) 143 | { 144 | //cleanup content after no message received for 15 sec 145 | 146 | //remove old timer if one is set 147 | if(mCleanupTimer != null) 148 | clearTimeout(mCleanupTimer); 149 | 150 | //setup new timer that cleanup 151 | mCleanupTimer = setTimeout(function() 152 | { 153 | //make sure the whole thing is still running 154 | if(mRunning == true && mFirebase != null) 155 | DeleteMessageLog(); 156 | mCleanupTimer = null; 157 | }, 15000); 158 | } 159 | 160 | var lMsg = lFirebaseMsg.val(); 161 | if(mRunning) 162 | { 163 | if(lMsg != null) 164 | { 165 | //check if it is a message for our protocol 166 | if(typeof lMsg.m === 'string') 167 | mHandler(SignalingMessageType.UserMessage, lMsg.m); 168 | }else if(lMsg == null && mIsRoomOwner == false) 169 | { 170 | //room content removed -> closed 171 | InternalClose(); 172 | } 173 | } 174 | 175 | }; 176 | 177 | /**Closes the signaling channel 178 | * 179 | * @returns {undefined} 180 | */ 181 | this.Close = function() 182 | { 183 | if(mFirebase != null && mIsRoomOwner) 184 | { 185 | 186 | mFirebase.remove(); 187 | } 188 | InternalClose(); 189 | }; 190 | 191 | function InternalClose() 192 | { 193 | 194 | if(mRunning) 195 | { 196 | mHandler(SignalingMessageType.Closed, null); 197 | } 198 | mRunning = false; 199 | mFirebase = null; 200 | 201 | } 202 | 203 | 204 | /**Sends a message over the signaling channel. 205 | * This can either be a broadcast to everyone in the room or be done more 206 | * securely by allowing only someone who connects to send to the server 207 | * and the other way around. The used protocol can work with both. 208 | * 209 | * @param {type} lMessage 210 | * @returns {undefined} 211 | */ 212 | this.SendMessage = function(lMessage) 213 | { 214 | //mFirebase.push({key : "message", value : lMessage}); 215 | if(mRunning && mFirebase != null) 216 | { 217 | var msg = {m : lMessage}; 218 | mFirebase.push(msg); 219 | } 220 | 221 | 222 | }; 223 | } 224 | -------------------------------------------------------------------------------- /jswebrtcnetwork/src/InterfaceSignalingChan.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | /**Definition of the interface. This just exists to make it easier to create 8 | * custom signaling channels. 9 | * 10 | * @returns {InterfaceSignalingChan} 11 | */ 12 | function InterfaceSignalingChan() 13 | { 14 | /**Opens a new room. Result will be: 15 | * * SignalingMessageType.Connected if the room is opened 16 | * * SignalingMessageType.Closed if the room is already opened 17 | * 18 | * @param {type} lName 19 | * @param {type} lHandler a function(SignalingMessageType, messageContent(string)); 20 | * @returns {undefined} 21 | */ 22 | this.Open = function(lName, lHandler) 23 | { 24 | }; 25 | 26 | /**Same as open but it only connects to an existing room 27 | * 28 | * @param {type} lName 29 | * @param {type} lHandler 30 | * @returns {undefined} 31 | */ 32 | this.Connect = function(lName, lHandler) 33 | { 34 | }; 35 | 36 | /**Closes the signaling channel 37 | * Will return SignalingMessageType.Closed via handler. 38 | * @returns {undefined} 39 | */ 40 | this.Close = function() 41 | { 42 | }; 43 | 44 | 45 | /**Sends a message over the signaling channel. 46 | * This can either be a broadcast to everyone in the room or be done more 47 | * securely by allowing only someone who connects to send to the server 48 | * and the other way around. The used protocol can work with both. 49 | * 50 | * @param {type} lMessage 51 | * @returns {undefined} 52 | */ 53 | this.SendMessage = function(lMessage) 54 | { 55 | }; 56 | } -------------------------------------------------------------------------------- /jswebrtcnetwork/src/JSONConnectorProtocol.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | 8 | 9 | //receives and sends json messages and delivers it in the right format to a peer 10 | //this other systems could implement different communication technologies or 11 | //treat the peers in browser specific ways 12 | //the connector will will return a finished event either after an error, success or timeout 13 | 14 | var ConnectorMessageType = { 15 | Invalid : 0, 16 | Offer : 1, 17 | Answer : 2, 18 | Ice : 3 19 | }; 20 | 21 | 22 | var JSONConnectorProtocol = function(lPeer, lSdpConstraints) 23 | { 24 | var mPeer = lPeer; 25 | var mSdpConstraints = lSdpConstraints; 26 | 27 | 28 | this.OnMessageDelivery = null; 29 | this.OnLog = null; 30 | this.OnError = null; 31 | this.OnStartConnecting = null; 32 | 33 | 34 | var self = this; 35 | //we set this to invalid just in case we work with a very chaoitic 36 | //message transmission system that could receive messages before we even 37 | //decided yet if we want to offer or wait for an offer 38 | var mExpectedMessageType = ConnectorMessageType.Invalid; 39 | 40 | 41 | var mOwnId; 42 | var mConId; 43 | 44 | /*Will immediately send out an offer and try to connect to who ever 45 | * reacts. 46 | * 47 | * 48 | * @returns {undefined} 49 | */ 50 | this.SendOffer = function() 51 | { 52 | mPeer.onicecandidate = OnIceCandidate; 53 | mOwnId = GetRandomId(); 54 | mExpectedMessageType = ConnectorMessageType.Answer; 55 | mPeer.createOffer(function (generatedOffer) 56 | { 57 | Log("createOffer"); 58 | mPeer.setLocalDescription(generatedOffer); 59 | 60 | 61 | var lMsg= { 62 | mtype: ConnectorMessageType.Offer, 63 | from : mOwnId, 64 | data: generatedOffer 65 | }; 66 | self.OnMessageDelivery(JSON.stringify(lMsg)); 67 | }, OnWebRtcFail, mSdpConstraints); 68 | //TODO: protocol 69 | if(self.OnStartConnecting != null) 70 | self.OnStartConnecting(); 71 | }; 72 | 73 | this.Cleanup = function() 74 | { 75 | //make sure to remove the references to the peer. 76 | mPeer.onicecandidate = null; 77 | mPeer = null; 78 | 79 | self.OnMessageDelivery = null; 80 | self.OnLog = null; 81 | self.OnError = null; 82 | self.OnStartConnecting = null; 83 | }; 84 | 85 | this.GetState = function() 86 | { 87 | return mExpectedMessageType; 88 | }; 89 | 90 | /**Sets the connector in wait mode. It will listen to all messages 91 | * it receives through OnMessageReceived until it finds an offer to 92 | * start etablishing a connection. 93 | * 94 | * @returns {undefined} 95 | */ 96 | this.WaitForOffer = function() 97 | { 98 | Log("WaitForOffer"); 99 | mPeer.onicecandidate = OnIceCandidate; 100 | mOwnId = GetRandomId(); 101 | mExpectedMessageType = ConnectorMessageType.Offer; 102 | 103 | //do nothing. just wait 104 | }; 105 | 106 | this.GetPeer = function() 107 | { 108 | return mPeer; 109 | }; 110 | //Called by the peer after offer and answer were exchanged 111 | function OnIceCandidate(e) 112 | { 113 | Log("onicecandidate"); 114 | if (!e || !e.candidate) return; 115 | 116 | var lMsg= { 117 | mtype: ConnectorMessageType.Ice, 118 | from : mOwnId, 119 | to : mConId, 120 | data: e.candidate 121 | }; 122 | self.OnMessageDelivery(JSON.stringify(lMsg)); 123 | 124 | } 125 | 126 | //called by the signaling channel if a message is received 127 | this.OnMessageReceived = function(lMsg) 128 | { 129 | var content = JSON.parse(lMsg); 130 | if(mExpectedMessageType === ConnectorMessageType.Offer 131 | && content.mtype == ConnectorMessageType.Offer) 132 | { 133 | //we have got an offer -> store the offer id and send out an answer 134 | mConId = content.from; 135 | 136 | //expect ice messages from the offerer 137 | mExpectedMessageType = ConnectorMessageType.Ice; 138 | 139 | if(self.OnStartConnecting != null) 140 | self.OnStartConnecting(); 141 | //first set the offer as session description 142 | mPeer.setRemoteDescription(new AnyRTCSessionDesc(content.data), function() 143 | { 144 | Log("setRemoteDescription offer"); 145 | //generate the answer 146 | mPeer.createAnswer(function (generatedAnswer) 147 | { 148 | Log("createAnswer"); 149 | //same as with offer -> set the answer as local descriptor 150 | mPeer.setLocalDescription(generatedAnswer); 151 | 152 | //answer message 153 | var lMsg= { 154 | mtype: ConnectorMessageType.Answer, 155 | from : mOwnId, //we include the offerer id so it is clear we answer this particular offer 156 | to : mConId, 157 | data: generatedAnswer 158 | }; 159 | 160 | //deliver the message 161 | self.OnMessageDelivery(JSON.stringify(lMsg)); 162 | 163 | }, OnWebRtcFail, mSdpConstraints);//error handler if mPeer.createAnswer fails 164 | 165 | }, OnWebRtcFail); //error handler if setRemoteDescription 166 | 167 | } 168 | else if(mExpectedMessageType === ConnectorMessageType.Answer 169 | && content.mtype == ConnectorMessageType.Answer 170 | && content.to == mOwnId) 171 | { 172 | //add the id of the answerer to better filter out messages 173 | mConId = content.from; 174 | //wait for ice messages 175 | mExpectedMessageType = ConnectorMessageType.Ice; 176 | //TODO sending here 177 | mPeer.setRemoteDescription(new AnyRTCSessionDesc(content.data), function() 178 | { 179 | Log("setRemoteDescription answer"); 180 | //done? 181 | }, OnWebRtcFail); 182 | } 183 | else if(mExpectedMessageType === ConnectorMessageType.Ice 184 | && content.mtype == ConnectorMessageType.Ice 185 | /*&& content.to == mOwnId*/ 186 | && content.from == mConId) 187 | { 188 | Log("addIceCandidate"); 189 | mPeer.addIceCandidate(new AnyRTCIceCandidate(content.data)); 190 | }else 191 | { 192 | //message ignored 193 | //as it is suppose to be used with random chat libraries this 194 | //is normal as it might get its own messages back or other 195 | //people/connections send other things around 196 | } 197 | 198 | }; 199 | 200 | //called by webrtc to report any errors 201 | function OnWebRtcFail(lDomErr) 202 | { 203 | if(self.OnError != null) 204 | { 205 | self.OnError(lDomErr); 206 | } 207 | } 208 | function Log(lMsg) 209 | { 210 | if(self.OnLog != null) 211 | { 212 | self.OnLog(lMsg); 213 | } 214 | } 215 | function GetRandomId() 216 | { 217 | return Math.floor((Math.random() * 16777216)); 218 | } 219 | 220 | 221 | 222 | }; -------------------------------------------------------------------------------- /jswebrtcnetwork/src/LocalSignalingChan.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | 8 | /** 9 | * Constructor/Class for creating a local signaling channel 10 | * (acts as a server at the same time) 11 | * 12 | * 13 | * - Open will open a new room or return a closed message if the room is already open 14 | * - Connect will join a room or return a closed message 15 | * - Incomming events are: 16 | * * Connected if either opening or connecting to a room was successful 17 | * * Closed if connecting or opening failed or the network connection closed 18 | * * UserMessage if a message was received. This is suppose to be handled by a different system 19 | * 20 | * They are suppose to work like a forum. you can either open a post and wait for responses 21 | * or you respond to other peoples post thus in theory the signaling channel could 22 | * build on top of a forum or chat system, or even email tracking a subject as room name 23 | * 24 | * 25 | * Security is up to the underlaying system of the signaling channel. It can 26 | * ensure nothing and just use a room name to find each other in a big public 27 | * chat or it filters for only messages with the correct room name + assignes 28 | * ID's to the user that opens a room and the user that joins it to only allow 29 | * point to point connections (most save) 30 | * 31 | * The LocalSignalingChan provices only some security by enforcing 32 | * that only one person can open a room but it relays messages to everyone 33 | * connected thus others could interfere 34 | * 35 | * 36 | * 37 | */ 38 | function LocalSignalingChan() 39 | { 40 | var mRoomName = null; 41 | var mHandler = null; 42 | var mIsRoomOwner = false; 43 | var mRunning = false; 44 | 45 | 46 | this.Open = function(lName, lHandler) 47 | { 48 | if(lName in LocalSignalingChan.sRooms) 49 | { 50 | //room name already in use 51 | //TODO: Send error via OnSignalingMessage 52 | //or check first if the object is still active? 53 | lHandler(SignalingMessageType.Closed, null); 54 | }else 55 | { 56 | mIsRoomOwner = true; 57 | mRoomName = lName; 58 | mHandler = lHandler; 59 | LocalSignalingChan.sRooms[lName] = [this]; 60 | mRunning = true; 61 | mHandler(SignalingMessageType.Connected, null); 62 | } 63 | }; 64 | 65 | 66 | this.Connect = function(lName, lHandler) 67 | { 68 | if(lName in LocalSignalingChan.sRooms) 69 | { 70 | mIsRoomOwner = false; 71 | mRoomName = lName; 72 | mHandler = lHandler; 73 | LocalSignalingChan.sRooms[lName].push(this); 74 | mRunning = true; 75 | mHandler(SignalingMessageType.Connected, null); 76 | }else 77 | { 78 | //TODO: send out error here. room is missing 79 | lHandler(SignalingMessageType.Closed, null); 80 | } 81 | }; 82 | 83 | this.Close = function() 84 | { 85 | if(mRunning == false) 86 | return; 87 | if(mIsRoomOwner) 88 | { 89 | //close all except the own one to avoid stack overflow 90 | var lChannels = LocalSignalingChan.sRooms[mRoomName]; 91 | for(var index = 0; index < lChannels.length; index++) 92 | { 93 | if(lChannels[index] != this) 94 | { 95 | lChannels[index].Close(); 96 | } 97 | } 98 | 99 | //delete the whole room 100 | delete LocalSignalingChan.sRooms[mRoomName]; 101 | //disconnect all 102 | }else 103 | { 104 | var lChannels = LocalSignalingChan.sRooms[mRoomName]; 105 | for(var index = 0; index < lChannels.length; index++) 106 | { 107 | if(lChannels[index] == this) 108 | { 109 | lChannels.splice(index, 1); 110 | } 111 | } 112 | } 113 | 114 | mRunning = false; 115 | mHandler(SignalingMessageType.Closed, null); 116 | }; 117 | 118 | this.RecMessage = function(lMessage) 119 | { 120 | mHandler(SignalingMessageType.UserMessage, lMessage); 121 | }; 122 | 123 | //public method. Sends a message to all others connected to this room 124 | this.SendMessage = function(lMessage) 125 | { 126 | //iterate over all local signal channels using the same room name 127 | //also itself and relay the message 128 | var lChannels = LocalSignalingChan.sRooms[mRoomName]; 129 | for(var index = 0; index < lChannels.length; index++) 130 | { 131 | //lChannels[index].mHandler(lMessage); 132 | lChannels[index].RecMessage(lMessage); 133 | } 134 | }; 135 | } 136 | LocalSignalingChan.sRooms = {}; -------------------------------------------------------------------------------- /jswebrtcnetwork/src/SocketIoSignalingChan.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | /**Signaling channel using socket.io. 8 | * This is the client side library only! 9 | * Server is in the socketiosignalingserver folder. 10 | * 11 | * @param {type} lUrl e.g. http://localhost:3000 (make sure to include the port even if it is port 80) 12 | * 13 | */ 14 | function SocketIoSignalingChan(lUrl) 15 | { 16 | var socket; 17 | var mHandler = null; 18 | var mConnecting = false; 19 | var mConnected = false; 20 | 21 | var mUrl = "http://localhost:3000"; 22 | if(lUrl != null) 23 | mUrl = lUrl; 24 | 25 | /**Opens a new room. Result will be: 26 | * * SignalingMessageType.Connected if the room is opened 27 | * * SignalingMessageType.Closed if the room is already opened 28 | * 29 | * @param {type} lName 30 | * @param {type} lHandler a function(SignalingMessageType, messageContent(string)); 31 | * @returns {undefined} 32 | */ 33 | this.Open = function(lName, lHandler) 34 | { 35 | mHandler = lHandler; 36 | mConnecting = true; 37 | 38 | socket = CreateSocket(); 39 | socket.on('connect', function() { 40 | socket.emit('open room', lName); 41 | }); 42 | socket.on("room opened", function() { 43 | OnConnect(); 44 | }); 45 | SetupSocket(); 46 | }; 47 | 48 | /**Same as open but it only connects to an existing room 49 | * 50 | * @param {type} lName 51 | * @param {type} lHandler 52 | * @returns {undefined} 53 | */ 54 | this.Connect = function(lName, lHandler) 55 | { 56 | mHandler = lHandler; 57 | mConnecting = true; 58 | socket = CreateSocket(); 59 | socket.on('connect', function() { 60 | socket.emit('join room', lName); 61 | }); 62 | socket.on("room joined", function() { 63 | OnConnect(); 64 | }); 65 | SetupSocket(); 66 | }; 67 | 68 | function CreateSocket() 69 | { 70 | return io.connect(mUrl, {'force new connection': true, reconnection : false, timeout : 10000}); 71 | } 72 | 73 | function SetupSocket() 74 | { 75 | socket.on('connect_timeout', function() { 76 | OnClose(); 77 | }); 78 | socket.on('connect_error', function(msg) { 79 | OnClose(); 80 | }); 81 | socket.on('disconnect', function() { 82 | OnClose(); 83 | }); 84 | socket.on("msg", function(msg) { 85 | mHandler(SignalingMessageType.UserMessage, msg); 86 | }); 87 | } 88 | 89 | /**Closes the signaling channel 90 | * 91 | * @returns {undefined} 92 | */ 93 | this.Close = function() 94 | { 95 | socket.disconnect(); 96 | OnClose(); 97 | }; 98 | 99 | 100 | function OnConnect() 101 | { 102 | mConnecting = false; 103 | mConnected = true; 104 | mHandler(SignalingMessageType.Connected, null); 105 | } 106 | /** 107 | * Sends out close event if the system was connecting or connected in the first place. 108 | * 109 | * TODO: This might also be called because of a timeout 110 | */ 111 | function OnClose() 112 | { 113 | if(mConnecting || mConnected) 114 | { 115 | //only send out the event if the user wasn't informed yet 116 | //if both values are false the user either did never connect or 117 | //did call Close already and thus received a closed event already 118 | mHandler(SignalingMessageType.Closed, null); 119 | } 120 | mConnecting = false; 121 | mConnected = false; 122 | } 123 | 124 | /**Sends a message over the signaling channel. 125 | * This can either be a broadcast to everyone in the room or be done more 126 | * securely by allowing only someone who connects to send to the server 127 | * and the other way around. The used protocol can work with both. 128 | * 129 | * @param {type} lMessage 130 | * @returns {undefined} 131 | */ 132 | this.SendMessage = function(lMessage) 133 | { 134 | socket.emit('msg', lMessage); 135 | }; 136 | } -------------------------------------------------------------------------------- /jswebrtcnetwork/src/examples/test.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | TODO supply a title 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
TODO write content
18 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /jswebrtcnetwork/src/examples/testWebRtc.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | TODO supply a title 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
TODO write content
28 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /jswebrtcnetwork/src/examples/testWebRtcClient.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | TODO supply a title 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
TODO write content
27 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /jswebrtcnetwork/src/examples/testWebRtcServer.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | TODO supply a title 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
TODO write content
28 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /jswebrtcnetwork/test/helpers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | /** Helper for unity tests for systems that need polling. 8 | * 9 | * @param {type} lCondition a function returning true or false 10 | * false -> system keeps polling or times out after a while 11 | * true -> system calls lOnContinue handler 12 | * @param {type} lTimeout time until timeout in ms 13 | * @param {type} lFailMessage error message to print if the timeout is triggered 14 | * @param {type} lOnContinue function to call if the condition is true. used to check the results 15 | * 16 | */ 17 | function WaitFor(lCondition, lTimeout, lFailMessage, lOnContinue) 18 | { 19 | 20 | var interval = 10; 21 | var time = 0; 22 | var intervalId; 23 | 24 | 25 | 26 | intervalId = setInterval(function() 27 | { 28 | var result = lCondition(); 29 | if(result) 30 | { 31 | //console.debug("condition true" + result); 32 | clearInterval(intervalId); 33 | lOnContinue(); 34 | return; 35 | }else 36 | { 37 | //console.debug("poll" + result + time); 38 | } 39 | 40 | time += interval; 41 | if(time > lTimeout) 42 | { 43 | clearInterval(intervalId); 44 | fail(lFailMessage); 45 | } 46 | }, interval); 47 | } 48 | -------------------------------------------------------------------------------- /jswebrtcnetwork/test/readme karma.txt: -------------------------------------------------------------------------------- 1 | npm install -g karma-cli 2 | is needed to make it run properly -------------------------------------------------------------------------------- /jswebrtcnetwork/test/test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/jswebrtcnetwork/test/test.txt -------------------------------------------------------------------------------- /jswebrtcnetwork/test/unit/CAPIWebRtcNetworkTest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | describe("CAPIWebRtcNetworkTest", function() { 7 | // full scenario test for the CAPI. might be slow as it uses webrtc 8 | beforeEach(function() { 9 | //reset all opened rooms fore each test so they don't interfere 10 | LocalSignalingChan.sRooms = {}; 11 | }); 12 | 13 | 14 | it("CAPI create and release", function() 15 | { 16 | //expect(gCAPIWebRtcNetworkInstances[lIndex]).toBe(null); 17 | var lServer = CAPIWebRtcNetworkCreate(""); 18 | expect(gCAPIWebRtcNetworkInstances[lServer]).toBeDefined(); 19 | CAPIWebRtcNetworkRelease(lServer); 20 | expect(gCAPIWebRtcNetworkInstances[lServer]).not.toBeDefined(); 21 | }); 22 | 23 | 24 | 25 | it("CAPIWebRtcNetworkConnectMessages", function(done) 26 | { 27 | 28 | var lServer = CAPIWebRtcNetworkCreate(""); 29 | var lClient = CAPIWebRtcNetworkCreate(""); 30 | var roomName = "testname"; 31 | CAPIWebRtcNetworkStartServer(lServer, roomName); 32 | var lNetEvent; 33 | var step = 0; 34 | var serverSideConId = -1; 35 | var clientSideConId = -1; 36 | 37 | //guess this is the simplest way to test it 38 | //enforcing order of events on server and client but not inbetween 39 | setInterval(function() 40 | { 41 | //always first handle server events. if there are none then client 42 | switch(step) { 43 | case 0: //wait for server to be connected 44 | { 45 | lNetEvent = CAPIWebRtcNetworkDequeue(lServer); 46 | if(lNetEvent == null) 47 | break; 48 | 49 | //except the server to be initialized correctly 50 | expect(lNetEvent.netEventType).toBe(NetEventType.ServerInitialized); 51 | 52 | //connect client 53 | lNetEvent = CAPIWebRtcNetworkConnect(lClient, roomName); 54 | step++; 55 | } 56 | break; 57 | case 1: 58 | 59 | { 60 | lNetEvent = CAPIWebRtcNetworkDequeue(lServer); 61 | if(lNetEvent == null) 62 | break; 63 | //expect the server to notice the incomming connection 64 | expect(lNetEvent.netEventType).toBe(NetEventType.NewConnection); 65 | serverSideConId = lNetEvent.connectionId; 66 | step++; 67 | } 68 | break; 69 | case 2: 70 | { 71 | lNetEvent = CAPIWebRtcNetworkDequeue(lClient); 72 | if(lNetEvent == null) 73 | break; 74 | //expect the client to notice the new connection 75 | expect(lNetEvent.netEventType).toBe(NetEventType.NewConnection); 76 | clientSideConId = lNetEvent.connectionId; 77 | 78 | 79 | //send reliable from client to server and server to client 80 | var data = new Uint8Array(1); 81 | data[0] = 42; 82 | CAPIWebRtcNetworkSendData(lClient, clientSideConId, data, true); 83 | 84 | data[0] = 43; 85 | CAPIWebRtcNetworkSendData(lServer, serverSideConId, data, true); 86 | step++; 87 | } 88 | break; 89 | case 3: 90 | { 91 | lNetEvent = CAPIWebRtcNetworkDequeue(lServer); 92 | if(lNetEvent == null) 93 | break; 94 | 95 | expect(lNetEvent.netEventType).toBe(NetEventType.ReliableMessageReceived); 96 | expect(lNetEvent.data).not.toBe(null); 97 | console.debug(lNetEvent.data); 98 | expect(lNetEvent.data[0]).toBe(42); 99 | step++; 100 | } 101 | break; 102 | case 4: 103 | { 104 | lNetEvent = CAPIWebRtcNetworkDequeue(lClient); 105 | if(lNetEvent == null) 106 | break; 107 | 108 | expect(lNetEvent.netEventType).toBe(NetEventType.ReliableMessageReceived); 109 | expect(lNetEvent.data).not.toBe(null); 110 | console.debug(lNetEvent.data); 111 | expect(lNetEvent.data[0]).toBe(43); 112 | 113 | 114 | 115 | 116 | var data = new Uint8Array(1); 117 | data[0] = 44; 118 | CAPIWebRtcNetworkSendDataEm(lClient, clientSideConId, data, 0, data.length, false); 119 | 120 | 121 | 122 | data[0] = 45; 123 | CAPIWebRtcNetworkSendDataEm(lServer, serverSideConId, data, 0, data.length, false); 124 | 125 | step++; 126 | } 127 | break; 128 | case 5: 129 | { 130 | lNetEvent = CAPIWebRtcNetworkDequeue(lServer); 131 | if(lNetEvent == null) 132 | break; 133 | 134 | expect(lNetEvent.netEventType).toBe(NetEventType.UnreliableMessageReceived); 135 | expect(lNetEvent.data).not.toBe(null); 136 | console.debug(lNetEvent.data); 137 | expect(lNetEvent.data[0]).toBe(44); 138 | step++; 139 | } 140 | break; 141 | case 6: 142 | { 143 | lNetEvent = CAPIWebRtcNetworkDequeue(lClient); 144 | if(lNetEvent == null) 145 | break; 146 | 147 | expect(lNetEvent.netEventType).toBe(NetEventType.UnreliableMessageReceived); 148 | expect(lNetEvent.data).not.toBe(null); 149 | console.debug(lNetEvent.data); 150 | expect(lNetEvent.data[0]).toBe(45); 151 | done(); 152 | } 153 | break; 154 | default: 155 | done.fail("invalid step"); 156 | } 157 | 158 | console.log("step " + step + "/7"); 159 | }, 10); 160 | }, 10000); 161 | 162 | }); 163 | 164 | -------------------------------------------------------------------------------- /jswebrtcnetwork/test/unit/FirebaseSignalingTest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | describe("FirebaseSignaling", function() 7 | { 8 | //testing the signaling channel. turned off by default as they use network 9 | //and are very slow 10 | 11 | it("ServerOpenClose", function(done) 12 | { 13 | var server = new FirebaseSignalingChan(); 14 | 15 | var latestMessageType = null; 16 | var latestMessage = null; 17 | 18 | 19 | 20 | 21 | server.Open("Test", function(lMsgType, lMsg) 22 | { 23 | latestMessageType = lMsgType; 24 | latestMessage = lMsg; 25 | 26 | }); 27 | 28 | 29 | WaitFor(function(){return latestMessageType != null;}, 5000, "Server didn't open", function() 30 | { 31 | expect(latestMessageType).toBe(SignalingMessageType.Connected); 32 | latestMessageType = null; 33 | server.Close(); 34 | WaitForClose(); 35 | }); 36 | 37 | function WaitForClose() 38 | { 39 | WaitFor(function(){return latestMessageType != null;}, 3000, "Server didn't close", function() 40 | { 41 | expect(latestMessageType).toBe(SignalingMessageType.Closed); 42 | server.Close(); 43 | done(); 44 | }); 45 | } 46 | }, 10000); 47 | 48 | 49 | it("ServerOpen Connect ServerClose", function(done) 50 | { 51 | var server = new FirebaseSignalingChan(); 52 | var client = new FirebaseSignalingChan(); 53 | 54 | var latestMessageType = null; 55 | var latestMessage = null; 56 | var clientLatestMessageType = null; 57 | var clientLatestMessage = null; 58 | 59 | 60 | 61 | 62 | server.Open("Test", function(lMsgType, lMsg) 63 | { 64 | latestMessageType = lMsgType; 65 | latestMessage = lMsg; 66 | 67 | }); 68 | 69 | 70 | WaitFor(function(){return latestMessageType != null;}, 5000, "Server didn't open", function() 71 | { 72 | expect(latestMessageType).toBe(SignalingMessageType.Connected); 73 | latestMessageType = null; 74 | clientLatestMessageType = null; 75 | 76 | 77 | client.Connect("Test", function(lMsgType, lMsg) 78 | { 79 | clientLatestMessageType = lMsgType; 80 | clientLatestMessage = lMsg; 81 | }); 82 | WaitForClientConnect(); 83 | }); 84 | 85 | function WaitForClientConnect() 86 | { 87 | WaitFor(function(){return clientLatestMessageType != null;}, 3000, "Client didn't connect", function() 88 | { 89 | expect(clientLatestMessageType).toBe(SignalingMessageType.Connected); 90 | latestMessageType = null; 91 | clientLatestMessageType = null; 92 | 93 | server.Close(); 94 | WaitForServerClose(); 95 | 96 | }); 97 | } 98 | 99 | function WaitForServerClose() 100 | { 101 | WaitFor(function(){return latestMessageType != null;}, 3000, "Server didn't close", function() 102 | { 103 | expect(latestMessageType).toBe(SignalingMessageType.Closed); 104 | WaitForClientClose(); 105 | }); 106 | } 107 | function WaitForClientClose() 108 | { 109 | WaitFor(function(){return clientLatestMessageType != null;}, 3000, "Client didn't close", function() 110 | { 111 | expect(clientLatestMessageType).toBe(SignalingMessageType.Closed); 112 | done(); 113 | }); 114 | } 115 | 116 | }, 10000); 117 | 118 | it("Send Message test", function(done) 119 | { 120 | var server = new FirebaseSignalingChan(); 121 | var client = new FirebaseSignalingChan(); 122 | 123 | var latestMessageType = null; 124 | var latestMessage = null; 125 | var clientLatestMessageType = null; 126 | var clientLatestMessage = null; 127 | 128 | 129 | 130 | 131 | server.Open("Test", function(lMsgType, lMsg) 132 | { 133 | latestMessageType = lMsgType; 134 | latestMessage = lMsg; 135 | 136 | }); 137 | 138 | 139 | WaitFor(function(){return latestMessageType != null;}, 5000, "Server didn't open", function() 140 | { 141 | expect(latestMessageType).toBe(SignalingMessageType.Connected); 142 | latestMessageType = null; 143 | clientLatestMessageType = null; 144 | 145 | 146 | client.Connect("Test", function(lMsgType, lMsg) 147 | { 148 | clientLatestMessageType = lMsgType; 149 | clientLatestMessage = lMsg; 150 | }); 151 | WaitForClientConnect(); 152 | }); 153 | 154 | function WaitForClientConnect() 155 | { 156 | WaitFor(function(){return clientLatestMessageType != null;}, 3000, "Client didn't connect", function() 157 | { 158 | expect(clientLatestMessageType).toBe(SignalingMessageType.Connected); 159 | latestMessageType = null; 160 | clientLatestMessageType = null; 161 | 162 | client.SendMessage("test message"); 163 | WaitForMessageOnServer(); 164 | 165 | }); 166 | } 167 | function WaitForMessageOnServer() 168 | { 169 | WaitFor(function(){return latestMessageType != null;}, 100, "Server didn't receive message", function() 170 | { 171 | expect(latestMessageType).toBe(SignalingMessageType.UserMessage); 172 | expect(latestMessage).toBe("test message"); 173 | 174 | //end test here because there can be undefined messages on the server side 175 | done(); 176 | }); 177 | } 178 | }, 10000); 179 | }); -------------------------------------------------------------------------------- /jswebrtcnetwork/test/unit/JSONConnectorProtocolTest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | describe("JSONConnectorProtocolTest", function() { 7 | //just one test that runs the full connectin process in json 8 | //split this in individual tests later 9 | 10 | it("JSONConnectorProtocolTestFull", function(done) 11 | { 12 | 13 | //TODO: 14 | var IceConfig = {"iceServers":[{"url":"stun:stun.l.google.com:19302"}]}; 15 | 16 | //configuration for the peer to ensure that chrome and firefox get along 17 | var ConnectionConfig = 18 | { 19 | 'optional': [ 20 | {'DtlsSrtpKeyAgreement': true}, 21 | //{'RtpDataChannels': true} //this is required in firefox but not allowed in chrome? 22 | ] 23 | }; 24 | 25 | //this setups the "services" that are offered -> no audio, no video we only use data channels 26 | //used while 2 peers are connecting 27 | var SdpConstraints = 28 | { 29 | 'mandatory': { 'OfferToReceiveAudio': false, 'OfferToReceiveVideo': false} 30 | }; 31 | 32 | 33 | var mPeerConnectionA = new AnyRTCPeerConnection(IceConfig, ConnectionConfig); 34 | 35 | //need to setup this first so the browser knows what to write into the offer 36 | var mPeerConnectionAReliable = mPeerConnectionA.createDataChannel("reliable", {reliable: true}); 37 | mPeerConnectionAReliable.binaryType = "arraybuffer"; 38 | var mPeerConnectionAUnreliable = mPeerConnectionA.createDataChannel("unreliable", {reliable: false}); 39 | mPeerConnectionAUnreliable.binaryType = "arraybuffer"; 40 | 41 | var mPeerConnectionB = new AnyRTCPeerConnection(IceConfig, ConnectionConfig); 42 | 43 | 44 | 45 | var ConAReliable = false; 46 | var ConAUnreliable = false; 47 | var ConBReliable = false; 48 | var ConBUnreliable = false; 49 | 50 | mPeerConnectionAReliable.onopen = function() 51 | { 52 | console.log("mPeerConnectionAReliable.onopen"); 53 | ConAReliable = true; 54 | }; 55 | mPeerConnectionAUnreliable.onopen = function() 56 | { 57 | console.log("mPeerConnectionAUnreliable.onopen"); 58 | ConAUnreliable = true; 59 | }; 60 | 61 | mPeerConnectionB.ondatachannel = function(ev) 62 | { 63 | if(ev.channel.label == "reliable") 64 | { 65 | ev.channel.onopen = function() 66 | { 67 | ConBReliable = true; 68 | console.log("mPeerConnectionBReliable.onopen"); 69 | }; 70 | }else if(ev.channel.label == "unreliable") 71 | { 72 | ev.channel.onopen = function() 73 | { 74 | ConBUnreliable = true; 75 | console.log("mPeerConnectionBUnreliable.onopen"); 76 | 77 | if(ConAReliable && ConAUnreliable && ConBReliable && ConBUnreliable) 78 | { 79 | done(); 80 | } 81 | }; 82 | } 83 | }; 84 | 85 | 86 | function FromAToB(lMsg) 87 | { 88 | console.debug("FromAToB: " + lMsg); 89 | mConnectorB.OnMessageReceived(lMsg); 90 | } 91 | function FromBToA(lMsg) 92 | { 93 | console.debug("FromBToA: " + lMsg); 94 | mConnectorA.OnMessageReceived(lMsg); 95 | } 96 | var mConnectorA = new JSONConnectorProtocol(mPeerConnectionA, SdpConstraints); 97 | mConnectorA.OnMessageDelivery = FromAToB; 98 | mConnectorA.OnError = function(lError, lConnector) 99 | { 100 | done.fail(lError); 101 | }; 102 | mConnectorA.OnStartConnecting = function() 103 | { 104 | console.debug("mConnectorA.OnStartConnecting"); 105 | }; 106 | var mConnectorB = new JSONConnectorProtocol(mPeerConnectionB, SdpConstraints); 107 | mConnectorB.OnMessageDelivery = FromBToA; 108 | mConnectorA.OnError = function(lError, lConnector) 109 | { 110 | done.fail(lError); 111 | }; 112 | mConnectorB.OnStartConnecting = function() 113 | { 114 | console.debug("mConnectorB.OnStartConnecting"); 115 | }; 116 | 117 | 118 | //A needs to be the one that sends the offer as it is the one that is configuratated 119 | //to create a data channel 120 | mConnectorB.WaitForOffer(); 121 | mConnectorA.SendOffer(); 122 | 123 | 124 | 125 | }); 126 | }); 127 | -------------------------------------------------------------------------------- /jswebrtcnetwork/test/unit/LocalSignalingTest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | describe("LocalSignaling", function() { 7 | 8 | beforeEach(function() { 9 | //reset all opened rooms fore each test so they don't interfere 10 | LocalSignalingChan.sRooms = {}; 11 | }); 12 | 13 | it("ServerOpenClose", function() 14 | { 15 | var server = new LocalSignalingChan(); 16 | 17 | var latestMessageType = null; 18 | var latestMessage = null; 19 | 20 | server.Open("Test", function(lMsgType, lMsg) 21 | { 22 | latestMessageType = lMsgType; 23 | latestMessage = lMsg; 24 | 25 | }); 26 | 27 | expect(latestMessageType).toBe(SignalingMessageType.Connected); 28 | expect(latestMessage).toBe(null); 29 | 30 | 31 | var messageContent = "test"; 32 | server.SendMessage(messageContent); 33 | expect(latestMessageType).toBe(SignalingMessageType.UserMessage); 34 | expect(latestMessage).toBe(messageContent); 35 | 36 | server.Close(); 37 | expect(latestMessageType).toBe(SignalingMessageType.Closed); 38 | expect(latestMessage).toBe(null); 39 | }); 40 | it("ServerClient", function() 41 | { 42 | var testRoomName = "TestRoom"; 43 | var server = new LocalSignalingChan(); 44 | var client = new LocalSignalingChan(); 45 | 46 | var latestServerMessageType = null; 47 | var latestServerMessage = null; 48 | 49 | server.Open(testRoomName, function(lMsgType, lMsg) 50 | { 51 | latestServerMessageType = lMsgType; 52 | latestServerMessage = lMsg; 53 | 54 | }); 55 | expect(latestServerMessageType).toBe(SignalingMessageType.Connected); 56 | expect(latestServerMessage).toBe(null); 57 | 58 | var latestClientMessageType = null; 59 | var latestClientMessage = null; 60 | 61 | client.Connect(testRoomName, function(lMsgType, lMsg) 62 | { 63 | latestClientMessageType = lMsgType; 64 | latestClientMessage = lMsg; 65 | }); 66 | expect(latestClientMessageType).toBe(SignalingMessageType.Connected); 67 | expect(latestClientMessage).toBe(null); 68 | 69 | 70 | var messageContent = "test"; 71 | server.SendMessage(messageContent); 72 | expect(latestServerMessageType).toBe(SignalingMessageType.UserMessage); 73 | expect(latestServerMessage).toBe(messageContent); 74 | expect(latestClientMessageType).toBe(SignalingMessageType.UserMessage); 75 | expect(latestClientMessage).toBe(messageContent); 76 | 77 | var messageContent = "test2"; 78 | client.SendMessage(messageContent); 79 | expect(latestServerMessageType).toBe(SignalingMessageType.UserMessage); 80 | expect(latestServerMessage).toBe(messageContent); 81 | expect(latestClientMessageType).toBe(SignalingMessageType.UserMessage); 82 | expect(latestClientMessage).toBe(messageContent); 83 | 84 | 85 | server.Close(); 86 | expect(latestServerMessageType).toBe(SignalingMessageType.Closed); 87 | expect(latestServerMessage).toBe(null); 88 | expect(latestClientMessageType).toBe(SignalingMessageType.Closed); 89 | expect(latestClientMessage).toBe(null); 90 | 91 | }); 92 | }); -------------------------------------------------------------------------------- /jswebrtcnetwork/test/unit/LocalWebRTCTest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | describe("LocalWebRTC", function() { 7 | //just a test to find errors in the use of webrtc. doesn't test code of the project 8 | 9 | it("FullScenario", function(done) 10 | { 11 | //getting rtc class names of various browsers 12 | var AnyRTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || 13 | window.webkitRTCPeerConnection || window.msRTCPeerConnection; 14 | var AnyRTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || 15 | window.webkitRTCIceCandidate; 16 | 17 | var AnyRTCSessionDesc = window.RTCSessionDescription || window.mozRTCSessionDescription || 18 | window.webkitRTCSessionDescription; 19 | 20 | 21 | 22 | //TODO: 23 | var IceConfig = {"iceServers":[{"url":"stun:stun.l.google.com:19302"}]}; 24 | 25 | //configuration for the peer to ensure that chrome and firefox get along 26 | var ConnectionConfig = 27 | { 28 | 'optional': [ 29 | {'DtlsSrtpKeyAgreement': true}, 30 | //{'RtpDataChannels': true} //this is required in firefox but not allowed in chrome? 31 | ] 32 | }; 33 | 34 | //this setups the "services" that are offered -> no audio, no video we only use data channels 35 | //used while 2 peers are connecting 36 | var SdpConstraints = 37 | { 38 | 'mandatory': { 'OfferToReceiveAudio': false, 'OfferToReceiveVideo': false} 39 | }; 40 | function OnFailture(domError) 41 | { 42 | done.fail(domError); 43 | //error callback used while creating offers/answers 44 | } 45 | 46 | 47 | var mPeerConnectionA = new AnyRTCPeerConnection(IceConfig, ConnectionConfig); 48 | //need to setup this first so the browser knows what to write into the offer 49 | var mDataChannelReliable = mPeerConnectionA.createDataChannel("reliable", {reliable: true}); 50 | mDataChannelReliable.binaryType = "arraybuffer"; 51 | var mDataChannelUnreliable = mPeerConnectionA.createDataChannel("unreliable", {reliable: false}); 52 | mDataChannelUnreliable.binaryType = "arraybuffer"; 53 | 54 | 55 | 56 | var mPeerConnectionB = new AnyRTCPeerConnection(IceConfig, ConnectionConfig); 57 | mPeerConnectionA.onicecandidate = function(e) 58 | { 59 | console.log("mPeerConnectionA.onicecandidate"); 60 | if (!mPeerConnectionA || !e || !e.candidate) return; 61 | //deliver the message to the other connection 62 | mPeerConnectionB.addIceCandidate(new AnyRTCIceCandidate(e.candidate)); 63 | 64 | }; 65 | mPeerConnectionB.onicecandidate = function(e) 66 | { 67 | console.log("mPeerConnectionB.onicecandidate"); 68 | if (!mPeerConnectionB || !e || !e.candidate) return; 69 | //deliver the message to the other connection 70 | mPeerConnectionA.addIceCandidate(new AnyRTCIceCandidate(e.candidate)); 71 | }; 72 | 73 | mPeerConnectionA.oniceconnectionstatechange = function() 74 | { 75 | console.log("mPeerConnectionA.oniceconnectionstatechange " + mPeerConnectionA.iceConnectionState); 76 | if(mPeerConnectionA.iceConnectionState == 'connected' 77 | || mPeerConnectionA.iceConnectionState == 'completed') 78 | { 79 | done(); 80 | } 81 | }; 82 | mPeerConnectionB.oniceconnectionstatechange = function() 83 | { 84 | console.log("mPeerConnectionB.oniceconnectionstatechange " + mPeerConnectionB.iceConnectionState); 85 | if(mPeerConnectionB.iceConnectionState == 'connected' 86 | || mPeerConnectionB.iceConnectionState == 'completed') 87 | { 88 | done(); 89 | } 90 | }; 91 | 92 | 93 | //make connection a create an offer for connection B 94 | mPeerConnectionA.createOffer(function (generatedOffer) 95 | { 96 | console.log("mPeerConnectionA.createOffer"); 97 | //set the local session description 98 | mPeerConnectionA.setLocalDescription(generatedOffer); 99 | 100 | //send the offer to the other peer 101 | 102 | //set the offer. after this is done it will call the next callback to create an answer 103 | mPeerConnectionB.setRemoteDescription(new AnyRTCSessionDesc(generatedOffer), function() 104 | { 105 | console.log("mPeerConnectionB.setRemoteDescription"); 106 | //on success 107 | //LOG("offer remote description set"); 108 | //generate an answer and set it as local description 109 | mPeerConnectionB.createAnswer(function (generatedAnswer) 110 | { 111 | console.log("mPeerConnectionB.createAnswer"); 112 | //same as with offer -> set the answer as local descriptor 113 | mPeerConnectionB.setLocalDescription(generatedAnswer); 114 | 115 | //TODO sending here 116 | mPeerConnectionA.setRemoteDescription(new AnyRTCSessionDesc(generatedAnswer), function() 117 | { 118 | console.log("mPeerConnectionA.setRemoteDescription"); 119 | //done? 120 | }, OnFailture); 121 | 122 | }, OnFailture, SdpConstraints);//if it fails send the error and shut down 123 | }, OnFailture); //if it fails send the error and shut down 124 | 125 | }, OnFailture, SdpConstraints); //error callback and peer configuration 126 | 127 | 128 | }, 10000); 129 | 130 | }); -------------------------------------------------------------------------------- /jswebrtcnetwork/test/unit/WebRtcClientServerTest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | describe("WebRtcClientConnectorServerTest", function() { 7 | //tests the connect process of client / server 8 | //TODO: add a test for multiple clients / one server 9 | it("ClientServerConnection", function(done) 10 | { 11 | var calls = 0; 12 | function OnServerStarted() 13 | { 14 | calls++; 15 | console.debug("OnServerStarted"); 16 | } 17 | function OnServerStopped(lMsg) 18 | { 19 | console.error("OnServerStopped: " + lMsg); 20 | done.fail(); 21 | } 22 | function OnServerNewConnection() 23 | { 24 | calls++; 25 | if(calls == 3) 26 | done(); 27 | console.debug("OnServerNewConnection"); 28 | } 29 | 30 | function OnClientConnected() 31 | { 32 | calls++; 33 | if(calls == 3) 34 | done(); 35 | console.debug("OnClientConnected"); 36 | } 37 | function OnClientConnectionFailed(lMsg) 38 | { 39 | console.error("OnClientConnectionFailed " + lMsg); 40 | done.fail(); 41 | } 42 | 43 | var serverSignaling = new LocalSignalingChan(); 44 | var server = new WebRtcServerConnector(serverSignaling); 45 | server.OnServerStarted = OnServerStarted; 46 | server.OnServerStopped = OnServerStopped; 47 | server.OnNewConnection = OnServerNewConnection; 48 | server.OnLog = function(lMsg) 49 | { 50 | console.log("Server: " + lMsg); 51 | }; 52 | 53 | var clientSignaling = new LocalSignalingChan(); 54 | var client = new WebRtcClientConnector(clientSignaling); 55 | client.OnConnected = OnClientConnected; 56 | client.OnConnectionFailed = OnClientConnectionFailed; 57 | client.OnLog = function(lMsg) 58 | { 59 | console.log("Client: " + lMsg); 60 | }; 61 | 62 | //start 63 | server.StartServer("testroom"); 64 | client.Connect("testroom"); 65 | }, 5000); 66 | }); 67 | -------------------------------------------------------------------------------- /socketiosignalingserver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socketio-signaling-server", 3 | "version": "0.9", 4 | "description": "Signaling server for the SocketIoSignalingChan in WebRTCNetwork", 5 | "dependencies": { 6 | "express": "^4.10.2", 7 | "socket.io": "^1.3.7" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /socketiosignalingserver/public/SocketIoSignalingChan.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | //TODO: might be not the newest version. add a grunt copy rule to refresh this file 7 | 8 | function SocketIoSignalingChan(lUrl) 9 | { 10 | var socket; 11 | var mHandler = null; 12 | var mConnecting = false; 13 | var mConnected = false; 14 | 15 | var mUrl = "http://localhost:3000"; 16 | if(lUrl != null) 17 | mUrl = lUrl; 18 | 19 | /**Opens a new room. Result will be: 20 | * * SignalingMessageType.Connected if the room is opened 21 | * * SignalingMessageType.Closed if the room is already opened 22 | * 23 | * @param {type} lName 24 | * @param {type} lHandler a function(SignalingMessageType, messageContent(string)); 25 | * @returns {undefined} 26 | */ 27 | this.Open = function(lName, lHandler) 28 | { 29 | mHandler = lHandler; 30 | mConnecting = true; 31 | 32 | socket = CreateSocket(); 33 | socket.on('connect', function() { 34 | socket.emit('open room', lName); 35 | }); 36 | socket.on("room opened", function() { 37 | OnConnect(); 38 | }); 39 | SetupSocket(); 40 | }; 41 | 42 | /**Same as open but it only connects to an existing room 43 | * 44 | * @param {type} lName 45 | * @param {type} lHandler 46 | * @returns {undefined} 47 | */ 48 | this.Connect = function(lName, lHandler) 49 | { 50 | mHandler = lHandler; 51 | mConnecting = true; 52 | socket = CreateSocket(); 53 | socket.on('connect', function() { 54 | socket.emit('join room', lName); 55 | }); 56 | socket.on("room joined", function() { 57 | OnConnect(); 58 | }); 59 | SetupSocket(); 60 | }; 61 | 62 | function CreateSocket() 63 | { 64 | return io.connect(mUrl, {'force new connection': true, reconnection : false, timeout : 5000}); 65 | } 66 | 67 | function SetupSocket() 68 | { 69 | socket.on('connect_timeout', function() { 70 | OnClose(); 71 | }); 72 | socket.on('connect_error', function() { 73 | OnClose(); 74 | }); 75 | socket.on('disconnect', function() { 76 | OnClose(); 77 | }); 78 | socket.on("msg", function(msg) { 79 | mHandler(SignalingMessageType.UserMessage, msg); 80 | }); 81 | } 82 | 83 | /**Closes the signaling channel 84 | * 85 | * @returns {undefined} 86 | */ 87 | this.Close = function() 88 | { 89 | socket.disconnect(); 90 | OnClose(); 91 | }; 92 | 93 | 94 | function OnConnect() 95 | { 96 | mConnecting = false; 97 | mConnected = true; 98 | mHandler(SignalingMessageType.Connected, null); 99 | } 100 | /** 101 | * Sends out close event if the system was connecting or connected in the first place. 102 | * 103 | * TODO: This might also be called because of a timeout 104 | */ 105 | function OnClose() 106 | { 107 | if(mConnecting || mConnected) 108 | { 109 | //only send out the event if the user wasn't informed yet 110 | //if both values are false the user either did never connect or 111 | //did call Close already and thus received a closed event already 112 | mHandler(SignalingMessageType.Closed, null); 113 | } 114 | mConnecting = false; 115 | mConnected = false; 116 | } 117 | 118 | /**Sends a message over the signaling channel. 119 | * This can either be a broadcast to everyone in the room or be done more 120 | * securely by allowing only someone who connects to send to the server 121 | * and the other way around. The used protocol can work with both. 122 | * 123 | * @param {type} lMessage 124 | * @returns {undefined} 125 | */ 126 | this.SendMessage = function(lMessage) 127 | { 128 | socket.emit('msg', lMessage); 129 | }; 130 | } -------------------------------------------------------------------------------- /socketiosignalingserver/public/index.html: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | 8 | 9 | 10 | 11 | Socket.IO chat 12 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 |
34 | 86 | 87 | -------------------------------------------------------------------------------- /socketiosignalingserver/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | var express = require('express'); 8 | var app = express(); 9 | var http = require('http').Server(app); 10 | var io = require('socket.io')(http); 11 | 12 | //just for debugging purposes 13 | var connectionCount = 0; 14 | 15 | //here we keep track of the rooms 16 | var rooms = {}; 17 | 18 | //to allow cross domains / e.g. connects from a unity game hosted on any domain 19 | app.use(function(req, res, next) { 20 | res.header('Access-Control-Allow-Origin', '*'); 21 | res.header('Access-Control-Allow-Methods', 'GET, OPTIONS'); 22 | res.header('Access-Control-Allow-Headers', 'Content-Type'); 23 | return next(); 24 | }); 25 | 26 | //public folder contains a chat based ok the socket io example to test this script 27 | //uncomment to test 28 | //app.use(express.static('public')); 29 | 30 | //wait for connections via socket.io 31 | io.on('connection', function(socket) { 32 | 33 | console.log('a user connected'); 34 | connectionCount++; 35 | 36 | var lRoomName = null; 37 | var lRoomOwner = false; 38 | 39 | 40 | //event to open a new room and add the user 41 | //user will get disconnected immediately if there isn't a room available (part of the definition of SignalingChan) 42 | socket.on('open room', function(msg) { 43 | //room name still free? 44 | if((msg in rooms) == false) 45 | { 46 | //open the room 47 | rooms[msg] = [socket]; //room owner is always index 0 48 | lRoomName = msg; 49 | lRoomOwner = true; 50 | 51 | console.log('room opened: ' + msg); 52 | socket.emit('room opened', msg); 53 | } 54 | else 55 | { 56 | //disconnect the user if it failed 57 | socket.disconnect(); 58 | } 59 | }); 60 | 61 | //join event. either joins an existing room. if there is none -> disconnect 62 | socket.on('join room', function(msg) { 63 | //does the room exist? 64 | if(msg in rooms) 65 | { 66 | //join the room 67 | rooms[msg].push(socket); 68 | lRoomName = msg; 69 | lRoomOwner = false; 70 | 71 | console.log('joined room: ' + msg); 72 | socket.emit('room joined', msg); 73 | } 74 | else 75 | { 76 | //disconnect the user if it failed 77 | socket.disconnect(); 78 | } 79 | }); 80 | 81 | //msg sends a message to everyone in the room 82 | socket.on('msg', function(msg) { 83 | 84 | if(lRoomName != null) //check if user is actually in a room 85 | { 86 | var socketsInRoom = rooms[lRoomName]; 87 | for(var index = 0; index < socketsInRoom.length; index++) 88 | { 89 | socketsInRoom[index].emit('msg', msg); 90 | } 91 | } 92 | }); 93 | 94 | //disconnect evet 95 | socket.on('disconnect', function() { 96 | 97 | if(lRoomOwner) 98 | { 99 | console.log('TODO: disconnect every socket in the room and then remove the room'); 100 | var socketsInRoom = rooms[lRoomName]; 101 | delete rooms[lRoomName]; 102 | 103 | for(var index = 1; index < socketsInRoom.length; index++) 104 | { 105 | socketsInRoom[index].disconnect(); 106 | } 107 | 108 | }else{ 109 | console.log('remove own socket from room list'); 110 | 111 | //room still exists or was closed? 112 | if(lRoomName != null && lRoomName in rooms) 113 | { 114 | //remove the element 115 | var index = rooms[lRoomName].indexOf(socket); 116 | if(index != -1) 117 | { 118 | rooms[lRoomName].splice(index, 1); 119 | } 120 | } 121 | } 122 | console.log('user disconnected'); 123 | connectionCount--; 124 | }); 125 | }); 126 | 127 | //process.env.PORT will be replaced with a pipe by azure 128 | var port = process.env.PORT || 3000; 129 | 130 | http.listen(port, function(){ 131 | 132 | console.log('listening on *:' + port); 133 | 134 | }); 135 | 136 | -------------------------------------------------------------------------------- /unitywebrtc/.gitignore: -------------------------------------------------------------------------------- 1 | /Temp 2 | /Library 3 | /unitywebrtc.sln 4 | /unitywebrtc.CSharp.csproj 5 | /unitywebrtc.v12.suo 6 | /jsunitywebrtc/node_modules 7 | /jsunitywebrtc/build 8 | /build 9 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/UnityProgress.js: -------------------------------------------------------------------------------- 1 | function UnityProgress (dom) { 2 | this.progress = 0.0; 3 | this.message = ""; 4 | this.dom = dom; 5 | 6 | var parent = dom.parentNode; 7 | 8 | var background = document.createElement("div"); 9 | background.style.background = "#4D4D4D"; 10 | background.style.position = "absolute"; 11 | parent.appendChild(background); 12 | this.background = background; 13 | 14 | var logoImage = document.createElement("img"); 15 | logoImage.src = "TemplateData/progresslogo.png"; 16 | logoImage.style.position = "absolute"; 17 | parent.appendChild(logoImage); 18 | this.logoImage = logoImage; 19 | 20 | var progressFrame = document.createElement("img"); 21 | progressFrame.src = "TemplateData/loadingbar.png"; 22 | progressFrame.style.position = "absolute"; 23 | parent.appendChild(progressFrame); 24 | this.progressFrame = progressFrame; 25 | 26 | var progressBar = document.createElement("img"); 27 | progressBar.src = "TemplateData/fullbar.png"; 28 | progressBar.style.position = "absolute"; 29 | parent.appendChild(progressBar); 30 | this.progressBar = progressBar; 31 | 32 | var messageArea = document.createElement("p"); 33 | messageArea.style.position = "absolute"; 34 | parent.appendChild(messageArea); 35 | this.messageArea = messageArea; 36 | 37 | 38 | this.SetProgress = function (progress) { 39 | if (this.progress < progress) 40 | this.progress = progress; 41 | this.messageArea.style.display = "none"; 42 | this.progressFrame.style.display = "inline"; 43 | this.progressBar.style.display = "inline"; 44 | this.Update(); 45 | } 46 | 47 | this.SetMessage = function (message) { 48 | this.message = message; 49 | this.background.style.display = "inline"; 50 | this.logoImage.style.display = "inline"; 51 | this.progressFrame.style.display = "none"; 52 | this.progressBar.style.display = "none"; 53 | this.Update(); 54 | } 55 | 56 | this.Clear = function() { 57 | this.background.style.display = "none"; 58 | this.logoImage.style.display = "none"; 59 | this.progressFrame.style.display = "none"; 60 | this.progressBar.style.display = "none"; 61 | } 62 | 63 | this.Update = function() { 64 | this.background.style.top = this.dom.offsetTop + 'px'; 65 | this.background.style.left = this.dom.offsetLeft + 'px'; 66 | this.background.style.width = this.dom.offsetWidth + 'px'; 67 | this.background.style.height = this.dom.offsetHeight + 'px'; 68 | 69 | var logoImg = new Image(); 70 | logoImg.src = this.logoImage.src; 71 | var progressFrameImg = new Image(); 72 | progressFrameImg.src = this.progressFrame.src; 73 | 74 | this.logoImage.style.top = this.dom.offsetTop + (this.dom.offsetHeight * 0.5 - logoImg.height * 0.5) + 'px'; 75 | this.logoImage.style.left = this.dom.offsetLeft + (this.dom.offsetWidth * 0.5 - logoImg.width * 0.5) + 'px'; 76 | this.logoImage.style.width = logoImg.width+'px'; 77 | this.logoImage.style.height = logoImg.height+'px'; 78 | 79 | this.progressFrame.style.top = this.dom.offsetTop + (this.dom.offsetHeight * 0.5 + logoImg.height * 0.5 + 10) + 'px'; 80 | this.progressFrame.style.left = this.dom.offsetLeft + (this.dom.offsetWidth * 0.5 - progressFrameImg.width * 0.5) + 'px'; 81 | this.progressFrame.width = progressFrameImg.width; 82 | this.progressFrame.height = progressFrameImg.height; 83 | 84 | this.progressBar.style.top = this.progressFrame.style.top; 85 | this.progressBar.style.left = this.progressFrame.style.left; 86 | this.progressBar.width = progressFrameImg.width * Math.min(this.progress, 1); 87 | this.progressBar.height = progressFrameImg.height; 88 | 89 | this.messageArea.style.top = this.progressFrame.style.top; 90 | this.messageArea.style.left = 0; 91 | this.messageArea.style.width = '100%'; 92 | this.messageArea.style.textAlign = 'center'; 93 | this.messageArea.innerHTML = this.message; 94 | } 95 | 96 | this.Update (); 97 | } -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/default-cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/default-cover.jpg -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/favicon.ico -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/fullbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/fullbar.png -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/fullscreen.png -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/loadingbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/loadingbar.png -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/logo.png -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/progresslogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devluz/webrtcnetwork/464a928723b361d887ebdd4b7afee616f9979f97/unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/progresslogo.png -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/TemplateData/style.css: -------------------------------------------------------------------------------- 1 | 2 | /**************************************** 3 | ==== RESETS 4 | ****************************************/ 5 | 6 | html,body,div,canvas { margin: 0; padding: 0; } 7 | /* 8 | ::-moz-selection { color: #333; text-shadow: none; } 9 | ::selection { color: #333; text-shadow: none; } 10 | */ 11 | .clear:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } 12 | .clear { display: inline-table; clear: both; } 13 | /* Hides from IE-mac \*/ * html .clear { height: 1%; } .clear { display: block; } /* End hide from IE-mac */ 14 | 15 | /**************************************** 16 | ==== LAYOUT 17 | ****************************************/ 18 | 19 | html, body { width: 100%; height: 100%; font-family: Helvetica, Verdana, Arial, sans-serif; } 20 | body { } 21 | p.header, p.footer { display: none; } 22 | div.logo { width: 204px; height: 38px; float: left; background: url(logo.png) 0 0 no-repeat; position: relative; z-index: 10; } 23 | div.title { height: 38px; line-height: 38px; padding: 0 10px; margin: 0 1px 0 0; float: right; color: #333; text-align: right; font-size: 18px; position: relative; z-index: 10; } 24 | .template-wrap { position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } 25 | .template-wrap canvas { margin: 0 0 10px 0; position: relative; z-index: 9; box-shadow: 0 10px 30px rgba(0,0,0,0.2); -moz-box-shadow: 0 10px 30px rgba(0,0,0,0.2); } 26 | .fullscreen { float: right; position: relative; z-index: 10; } 27 | 28 | body.template { } 29 | .template .template-wrap { } 30 | .template .template-wrap canvas { } 31 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebGLTemplates/WebRtcNetwork/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Unity WebGL Player | %UNITY_WEB_NAME% 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Unity WebGL Player | %UNITY_WEB_NAME%

15 | 16 | 17 | %UNITY_WEBGL_LOADER_GLUE% 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/Plugins/WebGL/WebRtcNetwork.jslib: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | var UnityWebRtcNetwork = 8 | { 9 | UnityWebRtcNetworkIsAvailable:function() 10 | { 11 | if(typeof CAPIWebRtcNetworkIsAvailable === 'function') 12 | { 13 | return CAPIWebRtcNetworkIsAvailable(); 14 | } 15 | return false; 16 | }, 17 | UnityWebRtcNetworkCreate:function(lConfiguration) 18 | { 19 | return CAPIWebRtcNetworkCreate(Pointer_stringify(lConfiguration)); 20 | }, 21 | UnityWebRtcNetworkRelease:function(lIndex) 22 | { 23 | CAPIWebRtcNetworkRelease(lIndex); 24 | }, 25 | UnityWebRtcNetworkConnect:function(lIndex, lRoom) 26 | { 27 | return CAPIWebRtcNetworkConnect(lIndex, Pointer_stringify(lRoom)); 28 | }, 29 | UnityWebRtcNetworkStartServer:function(lIndex, lRoom) 30 | { 31 | CAPIWebRtcNetworkStartServer(lIndex, Pointer_stringify(lRoom)); 32 | }, 33 | UnityWebRtcNetworkDisconnect:function(lIndex, lConnectionId) 34 | { 35 | CAPIWebRtcNetworkDisconnect(lIndex, lConnectionId); 36 | }, 37 | UnityWebRtcNetworkShutdown:function(lIndex) 38 | { 39 | CAPIWebRtcNetworkShutdown(lIndex); 40 | }, 41 | UnityWebRtcNetworkSendData:function(lIndex, lConnectionId, lUint8ArrayDataPtr, lUint8ArrayDataOffset, lUint8ArrayDataLength, lReliable) 42 | { 43 | var sndReliable = true; 44 | if(lReliable == false || lReliable == 0 || lReliable == "false" || lReliable == "False") 45 | sndReliable = false; 46 | CAPIWebRtcNetworkSendDataEm(lIndex, lConnectionId, HEAPU8, lUint8ArrayDataPtr + lUint8ArrayDataOffset, lUint8ArrayDataLength, sndReliable); 47 | }, 48 | UnityWebRtcNetworkPeekEventDataLength:function(lIndex) 49 | { 50 | return CAPIWebRtcNetworkPeekEventDataLength(lIndex); 51 | }, 52 | UnityWebRtcNetworkDequeue:function(lIndex, lTypeIntArrayPtr, lConidIntArrayPtr, lUint8ArrayDataPtr, lUint8ArrayDataOffset, lUint8ArrayDataLength, lDataLenIntArrayPtr ) 53 | { 54 | var val = CAPIWebRtcNetworkDequeueEm(lIndex, HEAP32, lTypeIntArrayPtr >> 2, HEAP32, lConidIntArrayPtr >> 2, HEAPU8, lUint8ArrayDataPtr + lUint8ArrayDataOffset, lUint8ArrayDataLength, HEAP32, lDataLenIntArrayPtr >> 2); 55 | 56 | //console.debug("event type: " + HEAP32[lTypeIntArrayPtr >> 2]); 57 | //console.debug("event conid: " + HEAP32[lConidIntArrayPtr >> 2]); 58 | return val; 59 | } 60 | }; 61 | 62 | mergeInto(LibraryManager.library, UnityWebRtcNetwork); -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Net/ByteArrayBuffer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using UnityEngine; 11 | 12 | namespace Luz.ULib.Net 13 | { 14 | 15 | public class ByteArrayBuffer : MessageDataBuffer 16 | { 17 | internal byte[] array; 18 | internal int positionWrite; 19 | internal int positionRead; 20 | 21 | //MessageDataBuffer interface 22 | public byte[] Buffer 23 | { 24 | get 25 | { 26 | if (mDisposed) 27 | throw new InvalidOperationException("Object is already disposed. No further use allowed."); 28 | return array; 29 | } 30 | } 31 | 32 | public int ContentLength 33 | { 34 | get 35 | { 36 | if (mDisposed) 37 | throw new InvalidOperationException("Object is already disposed. No further use allowed."); 38 | return positionWrite; 39 | } 40 | } 41 | 42 | 43 | 44 | private bool mFromPool = true; 45 | private bool mDisposed = false; 46 | 47 | public bool IsDisposed 48 | { 49 | get { return mDisposed; } 50 | } 51 | 52 | private ByteArrayBuffer(int size) 53 | { 54 | mFromPool = true; 55 | array = new byte[size]; 56 | positionWrite = 0; 57 | positionRead = 0; 58 | } 59 | public ByteArrayBuffer(byte[] arr) 60 | { 61 | mFromPool = false; //in case we have a pool system soon. all created with this constructor werent taken from the pool!!! mainly comes from unitys RPC function in UnityNetwork 62 | array = arr; 63 | positionRead = 0; 64 | positionWrite = arr.Length; 65 | } 66 | private void Reset() 67 | { 68 | mDisposed = false; 69 | positionRead = 0; 70 | positionWrite = 0; 71 | } 72 | ~ByteArrayBuffer() 73 | { 74 | if (mDisposed == false && mFromPool == true) 75 | { 76 | Debug.LogWarning("ByteArrayBuffer wasn't disposed."); 77 | } 78 | } 79 | 80 | public void CopyFrom(byte[] arr, int srcOffset, int len) 81 | { 82 | System.Buffer.BlockCopy(arr, srcOffset, this.array, 0, len); 83 | this.positionWrite = len; 84 | } 85 | 86 | private static List[] sPool = new List[32]; 87 | 88 | static ByteArrayBuffer() 89 | { 90 | for (int i = 0; i < sPool.Length; i++) 91 | { 92 | sPool[i] = new List(); 93 | } 94 | } 95 | 96 | 97 | 98 | static int[] MultiplyDeBruijnBitPosition = 99 | { 100 | 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 101 | 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 102 | }; 103 | private static int GetPower(uint anyPowerOfTwo) 104 | { 105 | uint index = (anyPowerOfTwo * 0x077CB531U) >> 27; 106 | return MultiplyDeBruijnBitPosition[(int)index]; 107 | } 108 | private static uint NextPowerOfTwo(uint v) 109 | { 110 | v |= v >> 1; 111 | v |= v >> 2; 112 | v |= v >> 4; 113 | v |= v >> 8; 114 | v |= v >> 16; 115 | v++; 116 | return v; 117 | } 118 | 119 | 120 | //List sPool[] = new List(); 121 | public static ByteArrayBuffer Get(int size) 122 | { 123 | uint pw = NextPowerOfTwo((uint)size); 124 | if (pw < 128) 125 | pw = 128; 126 | 127 | int index = GetPower(pw); 128 | 129 | if (sPool[index].Count == 0) 130 | { 131 | return new ByteArrayBuffer((int)pw); 132 | } 133 | else 134 | { 135 | List sizedPool = sPool[index]; 136 | ByteArrayBuffer buff = sizedPool[sizedPool.Count - 1]; 137 | sizedPool.RemoveAt(sizedPool.Count - 1); 138 | buff.Reset(); 139 | return buff; 140 | } 141 | //int powerOfTwo = 142 | } 143 | 144 | public void Dispose() 145 | { 146 | if (mDisposed) 147 | throw new InvalidOperationException("Object is already disposed. No further use allowed."); 148 | mDisposed = true; 149 | if (mFromPool) 150 | { 151 | int index = GetPower((uint)array.Length); 152 | sPool[index].Add(this); 153 | } 154 | } 155 | 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Net/ConnectionId.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace Luz.ULib.Net 12 | { 13 | /// 14 | /// Connection id idendifies one specific endpoint in a IBaseNetwork. 15 | /// 16 | /// They can only be used locally for a single instance of IBaseNetwork! 17 | /// 18 | [Serializable] 19 | public struct ConnectionId 20 | { 21 | 22 | /// 23 | /// ConnectionId 24 | /// 25 | public static readonly ConnectionId INVALID = new ConnectionId() { id = -1 }; 26 | 27 | /// 28 | /// Stores the id as a short. 29 | /// 30 | public short id; 31 | 32 | 33 | public override bool Equals(object obj) 34 | { 35 | if(obj is ConnectionId) 36 | { 37 | ConnectionId o = (ConnectionId)obj; 38 | return o == this; 39 | } 40 | return false; 41 | } 42 | 43 | public override int GetHashCode() 44 | { 45 | return id.GetHashCode(); 46 | } 47 | public static bool operator ==(ConnectionId i1, ConnectionId i2) 48 | { 49 | return i1.id == i2.id; 50 | } 51 | public static bool operator !=(ConnectionId i1, ConnectionId i2) 52 | { 53 | bool areEqual = i1 == i2; 54 | return !areEqual; 55 | } 56 | public static bool operator <(ConnectionId i1, ConnectionId i2) 57 | { 58 | return i1.id < i2.id; 59 | } 60 | public static bool operator >(ConnectionId i1, ConnectionId i2) 61 | { 62 | return i1.id > i2.id; 63 | } 64 | public static bool operator <=(ConnectionId i1, ConnectionId i2) 65 | { 66 | return i1.id <= i2.id; 67 | } 68 | public static bool operator >=(ConnectionId i1, ConnectionId i2) 69 | { 70 | return i1.id >= i2.id; 71 | } 72 | 73 | public override string ToString() 74 | { 75 | return id.ToString(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Net/IBasicNetwork.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | 9 | namespace Luz.ULib.Net 10 | { 11 | /// 12 | /// Interface to a network that doesn't enforce storing any states. 13 | /// 14 | /// Anything more is reusable between multiple different networks. 15 | /// 16 | public interface INetwork 17 | { 18 | /// 19 | /// This will return the incomming network events. Call this method and handle the incommen events until it returns false. 20 | /// 21 | /// 22 | /// Returns true if the parameter evt contains a new event. False if there are no events to process left. 23 | bool Dequeue(out NetworkEvent evt); 24 | 25 | /// 26 | /// Sends buffered data. 27 | /// 28 | void Flush(); 29 | 30 | /// 31 | /// Sends the content if a byte array to the given connection. 32 | /// 33 | /// The id of the recipient 34 | /// Byte array containing the data to send 35 | /// The index in data where the network should start to send 36 | /// Length in bytes you want to send 37 | /// True to send a reliable message(tcp style) and false to send unreliable (udp style) 38 | void SendData(ConnectionId id, byte[] data, int offset, int length, bool reliable); 39 | 40 | /// 41 | /// Disconnects the given connection 42 | /// 43 | /// Id of the connection to disconnect. 44 | void Disconnect(ConnectionId id); 45 | 46 | /// 47 | /// Disconnects all connection and shutsdown the server if started. 48 | /// Dequeue will still return the confirmation messages such as Disconnected event for each connection. 49 | /// 50 | /// 51 | void Shutdown(); 52 | 53 | /// 54 | /// Call this every frame if you intend to read incomming messages using Dequeue. This will make 55 | /// sure all data is read received by the network. 56 | /// 57 | void Update(); 58 | } 59 | /// 60 | /// Shared interface for WebRtcNetwork and UnityNetwork. 61 | /// 62 | /// Keep in mind that in the current version the network can only act as a server (StartServer method) or 63 | /// as a client (via Connect method). 64 | /// 65 | public interface IBasicNetwork : INetwork 66 | { 67 | /// 68 | /// List of all known connections 69 | /// 70 | IList Connections { get; } 71 | 72 | /// 73 | /// True if the system either runs in server mode or in client mode and is connected to a server. 74 | /// 75 | bool IsRunning { get; } 76 | 77 | /// 78 | /// True if the network runs in server mode and allows incomming connections. 79 | /// 80 | bool IsServer { get; } 81 | 82 | /// 83 | /// Starts a new server. After the server is started the Dequeue method will return a 84 | /// ServerInitialized event with the address in the Info field. 85 | /// 86 | /// If the server fails to start it will return a ServerInitFailed event. If the 87 | /// server is closed due to an error or the Shutdown method a ServerClosed event 88 | /// will be triggered. 89 | /// 90 | void StartServer(); 91 | 92 | 93 | /// 94 | /// Connects to a given address or roomname. 95 | /// 96 | /// This call will result in one of those 2 events in response: 97 | /// * NewConnection if the connection was etablished 98 | /// * ConnectionFailed if the connection failed. 99 | /// 100 | /// 101 | /// 102 | /// A string that idendifies the target. 103 | /// Returns the Connection id the etablished connection will have (only supported by WebRtcNetwork). 104 | ConnectionId Connect(string address); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Net/MessageDataBuffer.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace Luz.ULib.Net 12 | { 13 | /// 14 | /// 15 | /// This interface is used to return message data. 16 | /// 17 | /// Use MessageDataBuffer.Buffer only to read data between 18 | /// the index 0 and MessageDataBuffer.ContentLength. 19 | /// 20 | /// After reading use Dispose to allow the network to 21 | /// reuse this buffer and spare the Garbage Collector 22 | /// the work. 23 | /// 24 | /// Make sure not to keep any references to 25 | /// MessageDataBuffer.Buffer after calling Dispose! 26 | /// If you need to store the byte array creata a copy 27 | /// of the content before using Dispose. 28 | /// 29 | public interface MessageDataBuffer : IDisposable 30 | { 31 | /// 32 | /// Returns the buffer that contains the message data. 33 | /// Don't use Buffer.Length! The buffer might be longer than the actualy message. 34 | /// use ContentLength to get the length of the content 35 | /// 36 | byte[] Buffer 37 | { 38 | get; 39 | } 40 | 41 | /// 42 | /// Returns the length of the buffers content. 43 | /// The byte array might be longer than the actual content! 44 | /// Always use this property not Buffer.Length !!! 45 | /// 46 | int ContentLength 47 | { 48 | get; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Net/NetworkEvent.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace Luz.ULib.Net 12 | { 13 | /// 14 | /// Type of the received network event. 15 | /// 16 | public enum NetEventType : byte 17 | { 18 | Invalid = 0, 19 | UnreliableMessageReceived = 1, 20 | ReliableMessageReceived = 2, 21 | ServerInitialized = 3,//confirmation that the server was started. other people will be able to connect 22 | ServerInitFailed = 4,//server couldn't be started 23 | ServerClosed = 5,//server was closed. no new incomming connections 24 | NewConnection = 6,//new incomming or outgoing connection etablished 25 | ConnectionFailed = 7,//outgoing connection failed 26 | Disconnected = 8,//a connection was disconnected 27 | FatalError = 100, //not yet used 28 | Warning = 101,//not yet used 29 | Log = 102 //not yet used 30 | } 31 | 32 | /// 33 | /// Contains information about events received by the network. 34 | /// 35 | /// The type of the network event decides the content it can contain. 36 | /// 37 | /// Most important are: 38 | /// 39 | /// UnreliableMessageReceived / ReliableMessageReceived: 40 | /// A new message was received. The property MessageData will return 41 | /// a buffer + byte array containing the data received. 42 | /// 43 | /// ServerInitialized: 44 | /// A call to StartServer was successful. The Info property will return the address 45 | /// the server can be accessed by. 46 | /// 47 | /// 48 | /// 49 | public struct NetworkEvent 50 | { 51 | private NetEventType type; 52 | 53 | /// 54 | /// Returns the type of the message. 55 | /// 56 | public NetEventType Type 57 | { 58 | get 59 | { 60 | return type; 61 | } 62 | } 63 | 64 | private ConnectionId connectionId; 65 | 66 | /// 67 | /// Returns the related connection id or ConnecitonId.Invalid if there is none. 68 | /// 69 | public ConnectionId ConnectionId 70 | { 71 | get 72 | { 73 | return connectionId; 74 | } 75 | } 76 | 77 | 78 | private object data; 79 | 80 | /// 81 | /// Returns an object belonging to the event. 82 | /// This can be a MessageDataBuffer containing a byte array or a string. 83 | /// 84 | public object RawData 85 | { 86 | get { return data; } 87 | } 88 | /// 89 | /// Returns the content of the messages if the event type is 90 | /// UnreliableMessageReceived or ReliableMessageReceived. 91 | /// 92 | /// null for all other message types. 93 | /// 94 | public MessageDataBuffer MessageData 95 | { 96 | get 97 | { 98 | return data as MessageDataBuffer; 99 | } 100 | } 101 | 102 | /// 103 | /// Contains additional information or null 104 | /// Only used so far for NetEventType.ServerInitialized to return the servers address information. 105 | /// 106 | public string Info 107 | { 108 | get 109 | { 110 | return data as string; 111 | } 112 | } 113 | 114 | /// 115 | /// Creates a new network event of a certain type setting 116 | /// connection id to invalid and data to null. 117 | /// 118 | /// Internal only. Do not use. 119 | /// 120 | /// The type of this event 121 | internal NetworkEvent(NetEventType t) 122 | { 123 | type = t; 124 | connectionId = ConnectionId.INVALID; 125 | data = null; 126 | } 127 | 128 | /// 129 | /// Creates a network event with the given content 130 | /// 131 | /// Internal only. Do not use. 132 | /// 133 | /// Typename 134 | /// ConnectionId the event is from / relates to 135 | /// Data. String or MessageDataBuffer 136 | internal NetworkEvent(NetEventType t, ConnectionId conId, object dt) 137 | { 138 | type = t; 139 | connectionId = conId; 140 | data = dt; 141 | } 142 | 143 | /// 144 | /// Converts the event to string. Use for debugging only. 145 | /// 146 | /// A string representation of the network event. 147 | public override string ToString() 148 | { 149 | StringBuilder datastring = new StringBuilder(); 150 | datastring.Append("NetworkEvent type: "); 151 | datastring.Append(type); 152 | datastring.Append(" connection: "); 153 | datastring.Append(connectionId); 154 | datastring.Append(" data: "); 155 | 156 | if (data is ByteArrayBuffer) 157 | { 158 | ByteArrayBuffer msg = (ByteArrayBuffer)data; 159 | 160 | //datastring.Append(Encoding.ASCII.GetString(msg.array, msg.offset, msg.positionWrite)); 161 | datastring.Append(BitConverter.ToString(msg.array, 0, msg.positionWrite)); 162 | 163 | } 164 | else 165 | { 166 | datastring.Append(data); 167 | } 168 | return datastring.ToString(); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Net/SingleEndpointConnection.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using UnityEngine; 11 | 12 | 13 | namespace Luz.ULib.Net 14 | { 15 | 16 | #if !UNITY_WEBGL 17 | 18 | /// 19 | /// For internal use only. 20 | /// 21 | public class SingleEndpointConnection : MonoBehaviour 22 | { 23 | private NetworkView receiver; 24 | 25 | public NetworkView Receiver 26 | { 27 | get { return receiver; } 28 | set 29 | {receiver = value; } 30 | } 31 | private NetworkView sender; 32 | 33 | public NetworkView Sender 34 | { 35 | get { return sender; } 36 | set { sender = value; } 37 | } 38 | private NetworkPlayer connectedUser; 39 | 40 | public NetworkPlayer ConnectedUser 41 | { 42 | get { return connectedUser; } 43 | set { connectedUser = value; } 44 | } 45 | private UnityNetwork parent; 46 | 47 | public UnityNetwork Parent 48 | { 49 | get { return parent; } 50 | set { parent = value; } 51 | } 52 | 53 | public float uRefreshPerSecondSent = 16; 54 | public float uDebugRefreshPerSecondRec = 0; 55 | private int mRefreshSentSum = 0; 56 | private int mRefreshRecSum = 0; 57 | private float mLastAverage = 0; 58 | private void Awake() 59 | { 60 | 61 | } 62 | private void Start() 63 | { 64 | 65 | } 66 | private void Update() 67 | { 68 | mLastAverage += Time.deltaTime; 69 | if(mLastAverage > 1) 70 | { 71 | uDebugRefreshPerSecondRec = (uDebugRefreshPerSecondRec + mRefreshRecSum / mLastAverage) * 0.5f; 72 | uRefreshPerSecondSent = (uRefreshPerSecondSent + mRefreshSentSum / mLastAverage) * 0.5f; 73 | mLastAverage = 0; 74 | mRefreshRecSum = 0; 75 | mRefreshSentSum = 0; 76 | } 77 | } 78 | 79 | public void Init() 80 | { 81 | this.receiver.observed = this; 82 | this.sender.observed = this; 83 | if(Network.isServer) 84 | RefreshScope(); 85 | } 86 | 87 | public void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info) 88 | { 89 | if(stream.isReading) 90 | { 91 | mRefreshRecSum++; 92 | } 93 | else 94 | { 95 | mRefreshSentSum++; 96 | } 97 | parent.SingleEndpoint_OnSerialize(stream, ConnectedUser); 98 | } 99 | public void RefreshScope() 100 | { 101 | for(int i = 0; i < Network.connections.Length; i++) 102 | { 103 | if(connectedUser == Network.connections[i]) 104 | { 105 | sender.SetScope(Network.connections[i], true); 106 | } 107 | else 108 | { 109 | sender.SetScope(Network.connections[i], false); 110 | } 111 | } 112 | } 113 | 114 | } 115 | #endif 116 | } 117 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/ULib/Tools/DebugHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using UnityEngine; 11 | 12 | namespace Luz.ULib.Tools 13 | { 14 | public class DebugHelper 15 | { 16 | public static bool sShowConsole = false; 17 | public static bool sConsoleAutoScroll = true; 18 | 19 | private static Vector2 mDebugConsoleScrollPos = new Vector2(); 20 | private static StringBuilder mLog = null; 21 | private static int mLines = 0; 22 | 23 | public static void ActivateConsole() 24 | { 25 | if (mLog != null) 26 | return; 27 | mLog = new StringBuilder(); 28 | Application.logMessageReceived += LogType; 29 | } 30 | private static void LogType(string condition, string stackTrace, LogType type) 31 | { 32 | int lines = 0; 33 | mLog.Append(condition); 34 | if (type == UnityEngine.LogType.Exception) 35 | { 36 | lines += stackTrace.Count((x) => { return x == '\n'; }); 37 | mLog.Append(stackTrace); 38 | } 39 | mLog.Append("\n"); 40 | lines++; 41 | 42 | mLines += lines; 43 | 44 | int foundLines = 0; 45 | for (int i = mLog.Length - 1; i >= 0; i--) 46 | { 47 | if (mLog[i] == '\n') 48 | { 49 | foundLines++; 50 | if (foundLines == 100) 51 | { 52 | mLog.Remove(0, i + 1); 53 | break; 54 | } 55 | } 56 | } 57 | } 58 | public static void DrawConsole() 59 | { 60 | if (mLog == null) 61 | return;; 62 | 63 | if (sShowConsole == false) 64 | { 65 | if (GUI.Button(new Rect(Screen.width - 40, Screen.height - 20, 40, 20), "Show")) 66 | { 67 | sShowConsole = true; 68 | } 69 | } 70 | else 71 | { 72 | if (GUI.Button(new Rect(Screen.width - 40, Screen.height * 0.75f - 20, 40, 20), "Hide")) 73 | { 74 | sShowConsole = false; 75 | } 76 | if (GUI.Button(new Rect(Screen.width - 90, Screen.height * 0.75f - 20, 40, 20), "Auto")) 77 | { 78 | sConsoleAutoScroll = !sConsoleAutoScroll; 79 | } 80 | 81 | GUIStyle textStyle = new GUIStyle(); 82 | 83 | textStyle.normal.textColor = Color.white; 84 | textStyle.richText = true; 85 | 86 | GUI.Box(new Rect(0, Screen.height * 0.75f, Screen.width, Screen.height * 0.25f), ""); 87 | GUILayout.BeginArea(new Rect(0, Screen.height * 0.75f, Screen.width, Screen.height * 0.25f)); 88 | mDebugConsoleScrollPos = GUILayout.BeginScrollView(mDebugConsoleScrollPos); 89 | if(sConsoleAutoScroll) 90 | mDebugConsoleScrollPos = new Vector2(0, 1000000000); 91 | GUILayout.TextArea(mLog.ToString(), textStyle); 92 | GUILayout.EndScrollView(); 93 | GUILayout.EndArea(); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/example/ChatApp.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using UnityEngine; 7 | using System.Collections; 8 | using UnityEngine.UI; 9 | using Luz.ULib.Net; 10 | using System.Text; 11 | using System; 12 | using Luz.Net; 13 | using Luz.ULib.Tools; 14 | 15 | 16 | /// 17 | /// Contains a complete chat example. 18 | /// It can either run in the editor using the old unity network or in the browser as 19 | /// WebGL/HTML5 using WebRtc. 20 | /// 21 | /// The chat app will report during start which system it uses. 22 | /// 23 | /// The user can enter a room name and click the "Open room" button to start a server and wait for 24 | /// incomming connections or use the "Join room" button to join an already existing room. 25 | /// 26 | /// Note: Unity network uses random numbers / guid to idendify a server. The room name entered by the user 27 | /// will be ignored. 28 | /// 29 | /// 30 | /// As the system implements a server/client style connection all messages will first be sent to the 31 | /// server and the server delivers it to each client. The server side ConnectionId is used to 32 | /// idendify a user. 33 | /// 34 | /// 35 | /// 36 | public class ChatApp : MonoBehaviour 37 | { 38 | /// 39 | /// Input field used to enter the room name. 40 | /// 41 | public InputField uRoomName; 42 | 43 | /// 44 | /// Input field to enter a new message. 45 | /// 46 | public InputField uMessageField; 47 | 48 | /// 49 | /// Output message list to show incomming and sent messages + output messages of the 50 | /// system itself. 51 | /// 52 | public MessageList uOutput; 53 | 54 | /// 55 | /// Join button to connect to a server. 56 | /// 57 | public Button uJoin; 58 | 59 | /// 60 | /// Send button. 61 | /// 62 | public Button uSend; 63 | 64 | /// 65 | /// Open room button to start a server. 66 | /// 67 | public Button uOpenRoom; 68 | 69 | /// 70 | /// Shutdown button. Disconnects all connections + shuts down the server if started. 71 | /// 72 | public Button uShutdown; 73 | 74 | /// 75 | /// The network interface. Either UnityNetwork or 76 | /// 77 | private IBasicNetwork mNetwork = null; 78 | 79 | /// 80 | /// True if the user opened an own room allowing incomming connections 81 | /// 82 | private bool mIsServer = false; 83 | 84 | 85 | /// 86 | /// You can change the firebase version here (give this to the WebRtcNetwork constructor) 87 | /// 88 | private string mWebRtcConfig = "{ \"Signaling\" : { \"name\" : \"FirebaseSignalingChan\", \"conf\" : \"https://incandescent-inferno-5269.firebaseio.com/webrtcnetwork0_9/\"}}"; 89 | 90 | 91 | private void Start () 92 | { 93 | DebugHelper.ActivateConsole(); 94 | 95 | 96 | if(WebRtcNetwork.IsAvailable() == false) 97 | { 98 | //if the libray isn't available this could mean the JS part of the library is missing 99 | //(wrong template, webrtcnetworplugin.js not included -> try adding it via ExternalEval) 100 | Append("Try to initialize WebRTCNetwork"); 101 | WebRtcNetwork.InjectJsCode(); 102 | } 103 | 104 | if (WebRtcNetwork.IsAvailable()) 105 | { 106 | //default version 107 | //mNetwork = new WebRtcNetwork(); 108 | 109 | //custom configuration 110 | mNetwork = new WebRtcNetwork(mWebRtcConfig); 111 | Append("WebRtcNetwork available"); 112 | } 113 | else 114 | { 115 | Append("WebRtcNetwork not available"); 116 | 117 | if(UnityNetwork.IsAvailable()) 118 | { 119 | mNetwork = UnityNetwork.Get(); 120 | Append("Using unity network instead. TESTING ONLY! You can't connect to browsers."); 121 | Append("Build a WebGL example to use WebRTC!"); 122 | } 123 | else 124 | { 125 | Append("No network module available. Build and run a WebGL version or switch the platform to Standalone to use the Debugversion."); 126 | } 127 | } 128 | } 129 | 130 | /// 131 | /// Called if the Exit button is pressed. Quits the scene and shuts everything down. 132 | /// 133 | public void Exit() 134 | { 135 | //make sure to shutdown the network. This is usually not needed but (tested at version 5.2.1 4p) unity doesn't call 136 | //destructors reliably 137 | if (mNetwork != null) 138 | { 139 | mNetwork.Shutdown(); 140 | if (mNetwork is WebRtcNetwork) 141 | ((WebRtcNetwork)mNetwork).Dispose(); 142 | } 143 | Application.LoadLevel("menuscene"); 144 | } 145 | 146 | private void OnGUI() 147 | { 148 | //draws the debug console (or the show button in the corner to open it) 149 | DebugHelper.DrawConsole(); 150 | } 151 | 152 | 153 | /// 154 | /// Adds a new message to the message view 155 | /// 156 | /// 157 | private void Append(string text) 158 | { 159 | uOutput.AddTextEntry(text); 160 | } 161 | 162 | private void FixedUpdate() 163 | { 164 | //check each fixed update if we have got new events 165 | HandleNetwork(); 166 | } 167 | private void HandleNetwork() 168 | { 169 | //check if the network was created 170 | if (mNetwork != null) 171 | { 172 | //first update it to read the data from the underlaying network system 173 | mNetwork.Update(); 174 | 175 | //handle all new events that accured since the last update 176 | NetworkEvent evt; 177 | while (mNetwork.Dequeue(out evt)) 178 | { 179 | //print to the console for debugging 180 | Debug.Log(evt); 181 | 182 | //check every message 183 | switch (evt.Type) 184 | { 185 | case NetEventType.ServerInitialized: 186 | { 187 | //server initialized message received 188 | //this is the reaction to StartServer -> switch gui mode 189 | mIsServer = true; 190 | string address = evt.Info; 191 | Append("Server started. Address: " + address); 192 | uRoomName.text = "" + address; 193 | SetGuiState(false); 194 | } break; 195 | case NetEventType.ServerInitFailed: 196 | { 197 | //user tried to start the server but it failed 198 | //maybe the user is offline or signaling server down? 199 | mIsServer = false; 200 | Append("Server start failed."); 201 | SetGuiState(true); 202 | } break; 203 | case NetEventType.ServerClosed: 204 | { 205 | //server shut down. reaction to "Shutdown" call or 206 | //StopServer or the connection broke down 207 | mIsServer = false; 208 | Append("Server closed."); 209 | SetGuiState(true); 210 | } break; 211 | case NetEventType.NewConnection: 212 | { 213 | //either user runs a client and connected to a server or the 214 | //user runs the server and a new client connected 215 | Append("New local connection! ID: " + evt.ConnectionId); 216 | 217 | //if server -> send announcement to everyone and use the local id as username 218 | if(mIsServer) 219 | { 220 | //user runs a server. announce to everyone the new connection 221 | //using the server side connection id as idendification 222 | string msg = "New user " + evt.ConnectionId + " joined the room."; 223 | Append(msg); 224 | SendString(msg); 225 | } 226 | SetGuiState(false); 227 | } break; 228 | case NetEventType.ConnectionFailed: 229 | { 230 | //Outgoing connection failed. Inform the user. 231 | Append("Connection failed"); 232 | SetGuiState(true); 233 | } break; 234 | case NetEventType.Disconnected: 235 | { 236 | //A connection was disconnected 237 | //If this was the client then he was disconnected from the server 238 | //if it was the server this just means that one of the clients left 239 | Append("Local Connection ID " + evt.ConnectionId + " disconnected"); 240 | if(mNetwork.IsServer == false) 241 | { 242 | SetGuiState(true); 243 | } 244 | else 245 | { 246 | string userLeftMsg = "User " + evt.ConnectionId + " left the room."; 247 | 248 | //show the server the message 249 | Append(userLeftMsg); 250 | 251 | //other users left? inform them 252 | if (mNetwork.Connections.Count > 0) 253 | { 254 | SendString(userLeftMsg); 255 | } 256 | } 257 | } break; 258 | case NetEventType.ReliableMessageReceived: 259 | case NetEventType.UnreliableMessageReceived: 260 | { 261 | HandleIncommingMessage(ref evt); 262 | } break; 263 | } 264 | } 265 | 266 | //finish this update by flushing the messages out 267 | mNetwork.Flush(); 268 | } 269 | } 270 | 271 | private void HandleIncommingMessage(ref NetworkEvent evt) 272 | { 273 | MessageDataBuffer buffer = (MessageDataBuffer)evt.MessageData; 274 | 275 | string msg = Encoding.UTF8.GetString(buffer.Buffer, 0, buffer.ContentLength); 276 | 277 | //if server -> forward the message to everyone else including the sender 278 | if (mIsServer) 279 | { 280 | //we use the server side connection id to idendify the client 281 | string idAndMessage = evt.ConnectionId + ":" + msg; 282 | SendString(idAndMessage); 283 | Append(idAndMessage); 284 | } 285 | else 286 | { 287 | //client received a message from the server -> simply print 288 | Append(msg); 289 | } 290 | 291 | //return the buffer so the network can reuse it 292 | buffer.Dispose(); 293 | } 294 | 295 | /// 296 | /// Changes the gui depending on if the user is connected 297 | /// or disconnected 298 | /// 299 | /// true = user is connected. false = user isn't connected 300 | private void SetGuiState(bool isDisconnected) 301 | { 302 | uJoin.interactable = isDisconnected; 303 | uOpenRoom.interactable = isDisconnected; 304 | 305 | uSend.interactable = !isDisconnected; 306 | uShutdown.interactable = !isDisconnected; 307 | uMessageField.interactable = !isDisconnected; 308 | } 309 | 310 | /// 311 | /// Join button pressed. Tries to join a room. 312 | /// 313 | public void Join() 314 | { 315 | mNetwork.Connect(uRoomName.text); 316 | Append("Connect to " + uRoomName.text); 317 | } 318 | 319 | /// 320 | /// Open room button pressed. 321 | /// 322 | /// Opens a room / starts a server 323 | /// 324 | public void OpenRoom() 325 | { 326 | if(mNetwork is WebRtcNetwork) 327 | { 328 | ((WebRtcNetwork)mNetwork).StartServer(uRoomName.text); 329 | } 330 | else 331 | { 332 | mNetwork.StartServer(); 333 | } 334 | 335 | Debug.Log("StartServer " + uRoomName.text); 336 | } 337 | 338 | /// 339 | /// This is called if the send button 340 | /// 341 | public void SendButtonPressed() 342 | { 343 | //get the message written into the text field 344 | string msg = uMessageField.text; 345 | 346 | if(msg.StartsWith("/disconnect")) 347 | { 348 | string[] slt = msg.Split(' '); 349 | if(slt.Length >= 2) 350 | { 351 | ConnectionId conId; 352 | if (short.TryParse(slt[1], out conId.id)) 353 | { 354 | mNetwork.Disconnect(conId); 355 | } 356 | } 357 | } 358 | 359 | //if we are the server -> add 0 in front as the server id 360 | if(mIsServer) 361 | { 362 | //the server has the authority thus -> we can print it directly adding the 0 as server id 363 | msg = "0: " + msg; 364 | Append(msg); 365 | SendString(msg); 366 | } 367 | else 368 | { 369 | //clients just send it directly to the server. the server will decide what to do with it 370 | SendString(msg); 371 | } 372 | uMessageField.text = ""; 373 | } 374 | 375 | /// 376 | /// Sends a string as UTF8 byte array to all connections 377 | /// 378 | /// String containing the message to send 379 | /// false to use unrealiable messages / true to use reliable messages 380 | private void SendString(string msg, bool reliable = true) 381 | { 382 | if (mNetwork == null || mNetwork.Connections == null || mNetwork.Connections.Count == 0) 383 | { 384 | Append("No connection. Can't send message."); 385 | } 386 | else 387 | { 388 | byte[] msgData = Encoding.UTF8.GetBytes(msg); 389 | foreach (ConnectionId id in mNetwork.Connections) 390 | { 391 | mNetwork.SendData(id, msgData, 0, msgData.Length, reliable); 392 | } 393 | } 394 | } 395 | 396 | /// 397 | /// Shutdown button pressed. Shuts the network down. 398 | /// 399 | public void Shutdown() 400 | { 401 | if (mNetwork != null) 402 | mNetwork.Shutdown(); 403 | } 404 | 405 | } 406 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/example/LocalTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using UnityEngine; 7 | using System.Collections; 8 | using Luz.Net; 9 | using Luz.ULib.Net; 10 | using System.Text; 11 | 12 | /// 13 | /// Contains a test scenario. You can run this via the menuscene.scene file. 14 | /// Only works in a WebGL build! 15 | /// 16 | /// Local test will start one WebRtcNetwork as an echo server and one as a client. 17 | /// It will then connect, send a reliable/ unreliable message, test if those messages 18 | /// are received on the other and then disconnect again. 19 | /// 20 | /// Should end with ------------All tests successful!------------- in the debug console 21 | /// 22 | public class LocalTest : MonoBehaviour 23 | { 24 | private WebRtcNetwork mServer; 25 | private WebRtcNetwork mClient; 26 | 27 | private string mReliableTestMessage = ">>>RELIABLE MESSAGE<<<"; 28 | private string mUnreliableTestMessage = ">>>UNRELIABLE MESSAGE<<<"; 29 | 30 | 31 | 32 | public enum State 33 | { 34 | Uninitialized, 35 | ServerInit, 36 | ConnectClient, 37 | ReliableMessage, 38 | UnreliableMessage, 39 | TestSuccessful 40 | } 41 | 42 | /// 43 | /// State of the test. 44 | /// 45 | /// 46 | private State mState = State.Uninitialized; 47 | 48 | /// 49 | /// Called via UI 50 | /// 51 | public void StartTestButtonPressed() 52 | { 53 | if (WebRtcNetwork.IsAvailable() == false) 54 | { 55 | WebRtcNetwork.InjectJsCode(); 56 | } 57 | 58 | //Starts the test after 1 sec waiting to give the java script side of the library 59 | //time to download needed libraries 60 | //waiting time not needed if everything is included properly in the webgl template/sorrounding website 61 | StartCoroutine(CoroutineStartTestDelayed()); 62 | } 63 | private IEnumerator CoroutineStartTestDelayed() 64 | { 65 | yield return new WaitForSeconds(1); 66 | StartTest(); 67 | } 68 | 69 | private void StartTest() 70 | { 71 | 72 | if (WebRtcNetwork.IsAvailable() == false) 73 | { 74 | Debug.LogWarning("WebRtcNetwork not available. Please run it in WebGL to test WebRtcNetwork!"); 75 | } 76 | else 77 | { 78 | Debug.Log("WebRtcNetwork available. Starting test."); 79 | mServer = new WebRtcNetwork(); 80 | mClient = new WebRtcNetwork(); 81 | Debug.Log("Instance created"); 82 | 83 | mState = State.ServerInit; 84 | Debug.Log("Start test " + mState); 85 | mServer.StartServer(); 86 | } 87 | } 88 | 89 | private void FixedUpdate() 90 | { 91 | 92 | if(mServer != null) 93 | { 94 | mServer.Update(); 95 | 96 | NetworkEvent evt; 97 | while(mServer.Dequeue(out evt)) 98 | { 99 | Debug.Log("Server received event " + evt); 100 | if(evt.Type == NetEventType.ServerInitialized) 101 | { 102 | 103 | Debug.Log("Test " + mState + " successful!"); 104 | //server is started -> connect client 105 | mState = State.ConnectClient; 106 | Debug.Log("Start test " + mState); 107 | mClient.Connect(evt.Info); 108 | } 109 | else if (evt.Type == NetEventType.ReliableMessageReceived) 110 | { 111 | MessageDataBuffer buff = evt.MessageData; 112 | Debug.Log("server reliable message received:" + ToString(buff)); 113 | mServer.SendData(evt.ConnectionId, buff.Buffer, 0, buff.ContentLength, true); 114 | buff.Dispose(); 115 | } 116 | else if (evt.Type == NetEventType.UnreliableMessageReceived) 117 | { 118 | MessageDataBuffer buff = (MessageDataBuffer)evt.MessageData; 119 | Debug.Log("server unreliable message received:" + ToString(buff)); 120 | mServer.SendData(evt.ConnectionId, buff.Buffer, 0, buff.ContentLength, false); 121 | buff.Dispose(); 122 | } 123 | else if (evt.Type == NetEventType.Disconnected) 124 | { 125 | Debug.Log("Shutdown server"); 126 | mServer.Shutdown(); 127 | 128 | StartCoroutine(CoroutineCleanup()); 129 | } 130 | } 131 | } 132 | 133 | 134 | if(mClient != null) 135 | { 136 | mClient.Update(); 137 | NetworkEvent evt; 138 | while(mClient.Dequeue(out evt)) 139 | { 140 | Debug.Log("Client received event " + evt); 141 | 142 | if(evt.Type == NetEventType.NewConnection) 143 | { 144 | //send out test message 145 | 146 | Debug.Log("Test " + mState + " successful!"); 147 | mState = State.ReliableMessage; 148 | Debug.Log("Start test " + mState); 149 | byte[] data2 = Encoding.ASCII.GetBytes(mReliableTestMessage); 150 | mClient.SendData(evt.ConnectionId, data2, 0, data2.Length, true); 151 | } 152 | else if (evt.Type == NetEventType.ReliableMessageReceived) 153 | { 154 | MessageDataBuffer buff = evt.MessageData; 155 | 156 | string recMessage = ToString(buff); 157 | Debug.Log("client reliable message received:" + recMessage); 158 | if (mReliableTestMessage == recMessage) 159 | { 160 | Debug.Log("Reliable channel works"); 161 | } 162 | else 163 | { 164 | Debug.LogError("Expected " + mReliableTestMessage + " not " + recMessage); 165 | } 166 | buff.Dispose(); 167 | 168 | Debug.Log("Test " + mState + " successful!"); 169 | mState = State.UnreliableMessage; 170 | Debug.Log("Start test " + mState); 171 | byte[] data1 = Encoding.ASCII.GetBytes(mUnreliableTestMessage); 172 | mClient.SendData(evt.ConnectionId, data1, 0, data1.Length, false); 173 | 174 | } 175 | else if (evt.Type == NetEventType.UnreliableMessageReceived) 176 | { 177 | MessageDataBuffer buff = evt.MessageData; 178 | string recMessage = ToString(buff); 179 | Debug.Log("client unreliable message received:" + recMessage); 180 | if (mUnreliableTestMessage == recMessage) 181 | { 182 | Debug.Log("Unreliable channel works"); 183 | } 184 | else 185 | { 186 | Debug.LogError("Expected " + mUnreliableTestMessage + " not " + recMessage); 187 | } 188 | buff.Dispose(); 189 | 190 | Debug.Log("Test " + mState + " successful!"); 191 | mState = State.TestSuccessful; 192 | Debug.Log("All tests done!"); 193 | 194 | Debug.Log("Shutdown client"); 195 | mClient.Shutdown(); 196 | } 197 | } 198 | } 199 | } 200 | 201 | private IEnumerator CoroutineCleanup() 202 | { 203 | yield return new WaitForSeconds(5); 204 | mServer.Dispose(); 205 | mClient.Dispose(); 206 | mServer = null; 207 | mClient = null; 208 | if (mState == State.TestSuccessful) 209 | { 210 | Debug.Log("------------All tests successful!-------------"); 211 | } 212 | } 213 | 214 | private string ToString(MessageDataBuffer buff) 215 | { 216 | if (buff == null) 217 | return "no data"; 218 | if (buff.Buffer == null) 219 | return "content empty"; 220 | string content = Encoding.ASCII.GetString(buff.Buffer, 0, buff.ContentLength); 221 | return content; 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/example/MenuScene.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using UnityEngine; 7 | using System.Collections; 8 | using Luz.ULib.Tools; 9 | 10 | /// 11 | /// Simple script to draw the debug console and wait for ui events. 12 | /// 13 | public class MenuScene : MonoBehaviour { 14 | 15 | 16 | private void Start() 17 | { 18 | DebugHelper.ActivateConsole(); 19 | Debug.Log("Started ..."); 20 | } 21 | private void OnGUI() 22 | { 23 | DebugHelper.DrawConsole(); 24 | } 25 | 26 | public void LoadChat() 27 | { 28 | Application.LoadLevel("chatscene"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/example/MessageList.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using UnityEngine; 7 | using System.Collections; 8 | using System.Collections.Generic; 9 | using UnityEngine.UI; 10 | 11 | /// 12 | /// Shows a list of a text prefab. 13 | /// 14 | /// Used to show the messages that are sent/received in the ChatApp. 15 | /// 16 | public class MessageList : MonoBehaviour 17 | { 18 | /// 19 | /// References to the "Text" prefab. 20 | /// 21 | /// Needs to contain RectTransform and Text element. 22 | /// 23 | public GameObject uEntryPrefab; 24 | 25 | /// 26 | /// List of all text lines contained 27 | /// 28 | private Queue mElements = new Queue(); 29 | 30 | /// 31 | /// Reference to the own rect transform 32 | /// 33 | private RectTransform mOwnTransform; 34 | 35 | /// 36 | /// Number of messages until the older messages will be deleted. 37 | /// 38 | private int mMaxMessages = 60; 39 | 40 | 41 | private void Awake() 42 | { 43 | mOwnTransform = this.GetComponent(); 44 | } 45 | 46 | /// 47 | /// Allows the Chatapp to add new entires to the list 48 | /// 49 | /// Text to be added 50 | public void AddTextEntry(string text) 51 | { 52 | GameObject ngp = Instantiate(uEntryPrefab); 53 | Text t = ngp.GetComponentInChildren(); 54 | t.text = text; 55 | RectTransform transform = ngp.GetComponent(); 56 | AddRectTransform(transform); 57 | Refresh(); 58 | } 59 | 60 | /// 61 | /// Adds the new element 62 | /// 63 | /// 64 | private void AddRectTransform(RectTransform rect) 65 | { 66 | rect.SetParent(mOwnTransform, false); 67 | mElements.Enqueue(rect); 68 | 69 | } 70 | 71 | /// 72 | /// Destroys old messages if needed and repositions the existing messages. 73 | /// 74 | private void Refresh() 75 | { 76 | while(mElements.Count > mMaxMessages) 77 | { 78 | Destroy(mElements.Dequeue().gameObject); 79 | } 80 | 81 | 82 | float pos = 0; 83 | 84 | foreach (RectTransform rect in mElements) 85 | { 86 | SetPosition(rect, ref pos); 87 | } 88 | 89 | if(Mathf.Abs(pos) > mOwnTransform.rect.height) 90 | { 91 | Vector2 v = mOwnTransform.sizeDelta; 92 | 93 | v.y = Mathf.Abs(pos); 94 | mOwnTransform.sizeDelta = v; 95 | } 96 | } 97 | 98 | /// 99 | /// Positions a single element 100 | /// 101 | /// transform to be positioned 102 | /// Y position. Will be increased by the height of the current transform 103 | private void SetPosition(RectTransform tra, ref float position) 104 | { 105 | Vector2 pos = tra.anchoredPosition; 106 | pos = new Vector2(0, position); 107 | tra.anchoredPosition = pos; 108 | 109 | position -= tra.rect.height; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/example/Text.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &109896 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_PrefabParentObject: {fileID: 0} 7 | m_PrefabInternal: {fileID: 100100000} 8 | serializedVersion: 4 9 | m_Component: 10 | - 224: {fileID: 22437312} 11 | - 222: {fileID: 22231624} 12 | - 114: {fileID: 11421282} 13 | m_Layer: 5 14 | m_Name: Text 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!114 &11421282 21 | MonoBehaviour: 22 | m_ObjectHideFlags: 1 23 | m_PrefabParentObject: {fileID: 0} 24 | m_PrefabInternal: {fileID: 100100000} 25 | m_GameObject: {fileID: 109896} 26 | m_Enabled: 1 27 | m_EditorHideFlags: 0 28 | m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 29 | m_Name: 30 | m_EditorClassIdentifier: 31 | m_Material: {fileID: 0} 32 | m_Color: {r: .196078435, g: .196078435, b: .196078435, a: 1} 33 | m_RaycastTarget: 1 34 | m_OnCullStateChanged: 35 | m_PersistentCalls: 36 | m_Calls: [] 37 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 38 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 39 | m_FontData: 40 | m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} 41 | m_FontSize: 14 42 | m_FontStyle: 0 43 | m_BestFit: 0 44 | m_MinSize: 10 45 | m_MaxSize: 40 46 | m_Alignment: 3 47 | m_RichText: 1 48 | m_HorizontalOverflow: 0 49 | m_VerticalOverflow: 0 50 | m_LineSpacing: 1 51 | m_Text: New Text 52 | --- !u!222 &22231624 53 | CanvasRenderer: 54 | m_ObjectHideFlags: 1 55 | m_PrefabParentObject: {fileID: 0} 56 | m_PrefabInternal: {fileID: 100100000} 57 | m_GameObject: {fileID: 109896} 58 | --- !u!224 &22437312 59 | RectTransform: 60 | m_ObjectHideFlags: 1 61 | m_PrefabParentObject: {fileID: 0} 62 | m_PrefabInternal: {fileID: 100100000} 63 | m_GameObject: {fileID: 109896} 64 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 65 | m_LocalPosition: {x: 0, y: 0, z: 0} 66 | m_LocalScale: {x: 1, y: 1, z: 1} 67 | m_Children: [] 68 | m_Father: {fileID: 0} 69 | m_RootOrder: 0 70 | m_AnchorMin: {x: 0, y: 1} 71 | m_AnchorMax: {x: 1, y: 1} 72 | m_AnchoredPosition: {x: 0, y: 0} 73 | m_SizeDelta: {x: -10, y: 20} 74 | m_Pivot: {x: .5, y: 1} 75 | --- !u!1001 &100100000 76 | Prefab: 77 | m_ObjectHideFlags: 1 78 | serializedVersion: 2 79 | m_Modification: 80 | m_TransformParent: {fileID: 0} 81 | m_Modifications: 82 | - target: {fileID: 0} 83 | propertyPath: m_SizeDelta.y 84 | value: 20 85 | objectReference: {fileID: 0} 86 | m_RemovedComponents: [] 87 | m_ParentPrefab: {fileID: 0} 88 | m_RootGameObject: {fileID: 109896} 89 | m_IsPrefabParent: 1 90 | -------------------------------------------------------------------------------- /unitywebrtc/Assets/WebRtcNetwork/readme.txt: -------------------------------------------------------------------------------- 1 | Introduction: 2 | WebRTC Network is a plugin for Unity WebGL that allows two browsergames to connect 3 | DIRECTLY to each other and send reliable/unreliable messages using WebRTC Datachannels. 4 | This makes is well suited for any fast paced real time multiplayer games. 5 | 6 | WebRTC still requires a server to initialize the connection between two users. 7 | This version will automatically use a test server for this purpose (not suitable for a release version!). 8 | You can change the default server by using a firebase account (free for up to 30 CCU), 9 | websockets (coming soon) or your own system. If you have any questions feel free to contact me. 10 | 11 | Features: 12 | - Very simple programming interface. These are all methods you need: Start/StopServer, Connect, Disconnect, SendMessage + a Dequeue method to read incomming network events! 13 | - Send messages reliable or unreliable 14 | - Additional UnityNetwork class that allows you to test your network code outside of the browser 15 | - Contains a complete chat app as an example 16 | Note that Google and Mozilla treat WebRTC still as an experimental technology. 17 | 18 | Setup: 19 | Make sure you tick "Run in background" in your player settings. 20 | + add the example scenes to your build settings. 21 | 22 | Examples: 23 | The examples are stored in the folder WebRtcNetwork\example. 24 | This folder contains a chat application in the (chatscene.unity using ChatApp.cs) 25 | and test scenario to make sure the library works properly (menuscene.unity using LocalTest.cs). 26 | 27 | ChatApp: 28 | To start this app simply add it to the scenes list in your build settings at the top. To make sure 29 | the app uses WebRTC you need to build a WebGL build and then run it in firefox or chrome. 30 | It will use the old Unity network library to run in the editor and other platforms so you can 31 | test your network code without having to build a WebGL build first. 32 | 33 | The chat app allows a user to create a room or join a room. After entering a room the users can 34 | send chat messages to everyone in the room. The user that created the room will act as a server 35 | and relay the messages to all connected users. 36 | 37 | Use this example to learn how to use the library to send any data across the network. Keep in mind 38 | that naming a room is only possible in a browser not in unity editor as the unity network library 39 | doesn't support this feature. Also if you want to use the library in the editor make sure 40 | WebGL isn't selected as platform as this will block the editors network functionality. 41 | 42 | Test scenario: 43 | If you believe the library doesn't work properly you should try running the scene "menuscene.unity" 44 | in a WebGL build. It allows you to run a test to check if the library itself works properly in your 45 | browser and build configuration. You can find the documentation for the test in the file "LocalTest.cs". 46 | 47 | Other folders and files: 48 | Assets/WebRtcNetwork/ULib: 49 | Contains the C# side of the library. 50 | 51 | IBasicNetwork.cs defines the interface of the library 52 | WebRtcNetwork.cs implements the network functionality inside the browser in WebGL builds 53 | UnityNetwork.cs implements the network functionality for other platforms (for testing purposes) 54 | DebugHelper.cs shows a "Show" button in the right corner which will open the unity console outside 55 | of the UnityEditor for easy debugging! 56 | 57 | For detailed documentation please open the cs files. They are fully documented. 58 | 59 | Assets/WebRtcNetwork/Plugins: 60 | The folder contains a WebGL plugin "WebRtcNetwork.jslib" which allows the library to access js 61 | functions of the browser. 62 | 63 | Assets/WebRtcNetwork/Resources: 64 | Stores a file "webrtcnetworkplugin.txt" which is automatically generated. It contains the browser side 65 | code of the library and can be injected into the website via WebRtcNetwork.InjectJsCode(). 66 | This is only needed if your website doesn't include the needed js files. 67 | 68 | Assets/WebGLTemplates/WebRtcNetwork: 69 | Contains a template that makes sure all javascript files needed for the library are included into the 70 | WebGL build. You should use this instead of calling WebRtcNetwork.InjectJsCode() if possible. 71 | 72 | The basics (based on ChatApp.cs, please use the example to learn more!): 73 | 74 | First we need an instance that allows us to access the library. 75 | //check if the browser side library is available 76 | if(WebRtcNetwork.IsAvailable() == false) 77 | { 78 | //not yet available? try to inject the java script side 79 | WebRtcNetwork.InjectJsCode(); 80 | } 81 | 82 | //available now? 83 | if (WebRtcNetwork.IsAvailable()) 84 | { 85 | mNetwork = new WebRtcNetwork(mWebRtcConfig); 86 | } 87 | else 88 | { 89 | //browser side isn't available -> use unity network if possible 90 | if(UnityNetwork.IsAvailable()) 91 | { 92 | mNetwork = UnityNetwork.Get(); 93 | } 94 | else 95 | { 96 | //error can't create an instance 97 | } 98 | } 99 | 100 | Configuration: 101 | The browser side library needs a string to configure the library and determine which 102 | servers are suppose to be used to delegate the connection between multiple clients. 103 | 104 | The string should look like the following (JSON format + escaped \" for c#): 105 | 106 | string mWebRtcConfig = "{ \"Signaling\" : { \"name\" : \"FirebaseSignalingChan\", \"conf\" : \"https://incandescent-inferno-5269.firebaseio.com/webrtcnetwork0_9/\"}}"; 107 | 108 | Simply use this string and replace "https://incandescent-inferno-5269.firebaseio.com/webrtcnetwork0_9/" with your own 109 | firebase account. 110 | 111 | After you created the library you can use the methods: 112 | void StartServer() 113 | to allow incoming connections 114 | 115 | ConnectionId Connect(string address) 116 | to connect to a server 117 | 118 | bool Dequeue(out NetworkEvent evt); 119 | to handle incoming network events such as confirmation that the server was initialized (+ its address) 120 | as well as successful, failed outgoing connections 121 | 122 | If you established a connection to another peer use: 123 | 124 | void SendData(ConnectionId id, byte[] data, int offset, int length, bool reliable); 125 | to send a byte array to the other side. The needed connection id is delivered by the 126 | NewConnection NetworkEvent via Dequeue or can be accessed via the Connections property. 127 | 128 | You have questions or problems using the library? 129 | You can find up to date contact information at http://because-why-not.com/about/ 130 | or via the open source version of this library: https://github.com/devluz/webrtcnetwork 131 | 132 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 0 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_DisableAudio: 0 16 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Gravity: {x: 0, y: -9.81000042, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: .00499999989 11 | m_DefaultContactOffset: .00999999978 12 | m_SolverIterationCount: 6 13 | m_QueriesHitTriggers: 1 14 | m_EnableAdaptiveForce: 0 15 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 16 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/WebRtcNetwork/example/chatscene.unity 10 | - enabled: 1 11 | path: Assets/WebRtcNetwork/example/menuscene.unity 12 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_WebSecurityEmulationEnabled: 0 10 | m_WebSecurityEmulationHostUrl: http://www.mydomain.com/mygame.unity3d 11 | m_DefaultBehaviorMode: 1 12 | m_SpritePackerMode: 2 13 | m_SpritePackerPaddingPower: 1 14 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 15 | m_ProjectGenerationRootNamespace: 16 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_LegacyDeferred: 14 | m_Mode: 1 15 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 16 | m_AlwaysIncludedShaders: 17 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 18 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 19 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 20 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 21 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 22 | - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} 23 | m_PreloadedShaders: [] 24 | m_LightmapStripping: 0 25 | m_LightmapKeepPlain: 1 26 | m_LightmapKeepDirCombined: 1 27 | m_LightmapKeepDirSeparate: 1 28 | m_LightmapKeepDynamicPlain: 1 29 | m_LightmapKeepDynamicDirCombined: 1 30 | m_LightmapKeepDynamicDirSeparate: 1 31 | m_FogStripping: 0 32 | m_FogKeepLinear: 1 33 | m_FogKeepExp: 1 34 | m_FogKeepExp2: 1 35 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: .00100000005 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: .00100000005 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: .00100000005 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: .00100000005 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: .00100000005 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: .00100000005 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: .100000001 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: .100000001 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: .100000001 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: .189999998 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: .189999998 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: .00100000005 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: .00100000005 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: .00100000005 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: .00100000005 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: .00100000005 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: .00100000005 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: .00100000005 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshAreas: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Gravity: {x: 0, y: -9.81000042} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: .200000003 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_MinPenetrationForPenalty: .00999999978 17 | m_BaumgarteScale: .200000003 18 | m_BaumgarteTimeOfImpactScale: .75 19 | m_TimeToSleep: .5 20 | m_LinearSleepTolerance: .00999999978 21 | m_AngularSleepTolerance: 2 22 | m_QueriesHitTriggers: 1 23 | m_QueriesStartInColliders: 1 24 | m_ChangeStopsCallbacks: 0 25 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 26 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | AndroidProfiler: 0 8 | defaultScreenOrientation: 4 9 | targetDevice: 2 10 | targetResolution: 0 11 | useOnDemandResources: 0 12 | accelerometerFrequency: 60 13 | companyName: DefaultCompany 14 | productName: unitywebrtc 15 | defaultCursor: {fileID: 0} 16 | cursorHotspot: {x: 0, y: 0} 17 | m_ShowUnitySplashScreen: 1 18 | defaultScreenWidth: 1024 19 | defaultScreenHeight: 768 20 | defaultScreenWidthWeb: 960 21 | defaultScreenHeightWeb: 600 22 | m_RenderingPath: 1 23 | m_MobileRenderingPath: 1 24 | m_ActiveColorSpace: 0 25 | m_MTRendering: 1 26 | m_MobileMTRendering: 0 27 | m_Stereoscopic3D: 0 28 | iosShowActivityIndicatorOnLoading: -1 29 | androidShowActivityIndicatorOnLoading: -1 30 | iosAppInBackgroundBehavior: 0 31 | displayResolutionDialog: 1 32 | iosAllowHTTPDownload: 1 33 | allowedAutorotateToPortrait: 1 34 | allowedAutorotateToPortraitUpsideDown: 1 35 | allowedAutorotateToLandscapeRight: 1 36 | allowedAutorotateToLandscapeLeft: 1 37 | useOSAutorotation: 1 38 | use32BitDisplayBuffer: 1 39 | disableDepthAndStencilBuffers: 0 40 | defaultIsFullScreen: 1 41 | defaultIsNativeResolution: 1 42 | runInBackground: 1 43 | captureSingleScreen: 0 44 | Override IPod Music: 0 45 | Prepare IOS For Recording: 0 46 | submitAnalytics: 1 47 | usePlayerLog: 1 48 | bakeCollisionMeshes: 0 49 | forceSingleInstance: 0 50 | resizableWindow: 0 51 | useMacAppStoreValidation: 0 52 | gpuSkinning: 0 53 | xboxPIXTextureCapture: 0 54 | xboxEnableAvatar: 0 55 | xboxEnableKinect: 0 56 | xboxEnableKinectAutoTracking: 0 57 | xboxEnableFitness: 0 58 | visibleInBackground: 0 59 | macFullscreenMode: 2 60 | d3d9FullscreenMode: 1 61 | d3d11FullscreenMode: 1 62 | xboxSpeechDB: 0 63 | xboxEnableHeadOrientation: 0 64 | xboxEnableGuest: 0 65 | n3dsDisableStereoscopicView: 0 66 | n3dsEnableSharedListOpt: 1 67 | n3dsEnableVSync: 0 68 | xboxOneResolution: 0 69 | ps3SplashScreen: {fileID: 0} 70 | videoMemoryForVertexBuffers: 0 71 | psp2PowerMode: 0 72 | psp2AcquireBGM: 1 73 | wiiUTVResolution: 0 74 | wiiUGamePadMSAA: 1 75 | wiiUSupportsNunchuk: 0 76 | wiiUSupportsClassicController: 0 77 | wiiUSupportsBalanceBoard: 0 78 | wiiUSupportsMotionPlus: 0 79 | wiiUSupportsProController: 0 80 | wiiUAllowScreenCapture: 1 81 | wiiUControllerCount: 0 82 | m_SupportedAspectRatios: 83 | 4:3: 1 84 | 5:4: 1 85 | 16:10: 1 86 | 16:9: 1 87 | Others: 1 88 | bundleIdentifier: com.Company.ProductName 89 | bundleVersion: 1.0 90 | preloadedAssets: [] 91 | metroEnableIndependentInputSource: 0 92 | metroEnableLowLatencyPresentationAPI: 0 93 | xboxOneDisableKinectGpuReservation: 0 94 | virtualRealitySupported: 0 95 | productGUID: f41a19692ad49724dbf8c5f456e9f75a 96 | AndroidBundleVersionCode: 1 97 | AndroidMinSdkVersion: 9 98 | AndroidPreferredInstallLocation: 1 99 | aotOptions: 100 | apiCompatibilityLevel: 2 101 | stripEngineCode: 1 102 | iPhoneStrippingLevel: 0 103 | iPhoneScriptCallOptimization: 0 104 | iPhoneBuildNumber: 0 105 | ForceInternetPermission: 0 106 | ForceSDCardPermission: 0 107 | CreateWallpaper: 0 108 | APKExpansionFiles: 0 109 | preloadShaders: 0 110 | StripUnusedMeshComponents: 0 111 | VertexChannelCompressionMask: 112 | serializedVersion: 2 113 | m_Bits: 238 114 | iPhoneSdkVersion: 988 115 | iPhoneTargetOSVersion: 22 116 | uIPrerenderedIcon: 0 117 | uIRequiresPersistentWiFi: 0 118 | uIStatusBarHidden: 1 119 | uIExitOnSuspend: 0 120 | uIStatusBarStyle: 0 121 | iPhoneSplashScreen: {fileID: 0} 122 | iPhoneHighResSplashScreen: {fileID: 0} 123 | iPhoneTallHighResSplashScreen: {fileID: 0} 124 | iPhone47inSplashScreen: {fileID: 0} 125 | iPhone55inPortraitSplashScreen: {fileID: 0} 126 | iPhone55inLandscapeSplashScreen: {fileID: 0} 127 | iPadPortraitSplashScreen: {fileID: 0} 128 | iPadHighResPortraitSplashScreen: {fileID: 0} 129 | iPadLandscapeSplashScreen: {fileID: 0} 130 | iPadHighResLandscapeSplashScreen: {fileID: 0} 131 | iOSLaunchScreenType: 0 132 | iOSLaunchScreenPortrait: {fileID: 0} 133 | iOSLaunchScreenLandscape: {fileID: 0} 134 | iOSLaunchScreenBackgroundColor: 135 | serializedVersion: 2 136 | rgba: 0 137 | iOSLaunchScreenFillPct: 100 138 | iOSLaunchScreenSize: 100 139 | iOSLaunchScreenCustomXibPath: 140 | iOSLaunchScreeniPadType: 0 141 | iOSLaunchScreeniPadImage: {fileID: 0} 142 | iOSLaunchScreeniPadBackgroundColor: 143 | serializedVersion: 2 144 | rgba: 0 145 | iOSLaunchScreeniPadFillPct: 100 146 | iOSLaunchScreeniPadSize: 100 147 | iOSLaunchScreeniPadCustomXibPath: 148 | iOSDeviceRequirements: [] 149 | AndroidTargetDevice: 0 150 | AndroidSplashScreenScale: 0 151 | androidSplashScreen: {fileID: 0} 152 | AndroidKeystoreName: 153 | AndroidKeyaliasName: 154 | AndroidTVCompatibility: 1 155 | AndroidIsGame: 1 156 | androidEnableBanner: 1 157 | m_AndroidBanners: 158 | - width: 320 159 | height: 180 160 | banner: {fileID: 0} 161 | androidGamepadSupportLevel: 0 162 | resolutionDialogBanner: {fileID: 0} 163 | m_BuildTargetIcons: 164 | - m_BuildTarget: 165 | m_Icons: 166 | - serializedVersion: 2 167 | m_Icon: {fileID: 0} 168 | m_Width: 128 169 | m_Height: 128 170 | m_BuildTargetBatching: [] 171 | m_BuildTargetGraphicsAPIs: [] 172 | webPlayerTemplate: APPLICATION:Default 173 | m_TemplateCustomTags: {} 174 | wiiUTitleID: 0005000011000000 175 | wiiUGroupID: 00010000 176 | wiiUCommonSaveSize: 4096 177 | wiiUAccountSaveSize: 2048 178 | wiiUOlvAccessKey: 0 179 | wiiUTinCode: 0 180 | wiiUJoinGameId: 0 181 | wiiUJoinGameModeMask: 0000000000000000 182 | wiiUCommonBossSize: 0 183 | wiiUAccountBossSize: 0 184 | wiiUAddOnUniqueIDs: [] 185 | wiiUMainThreadStackSize: 3072 186 | wiiULoaderThreadStackSize: 1024 187 | wiiUSystemHeapSize: 128 188 | wiiUTVStartupScreen: {fileID: 0} 189 | wiiUGamePadStartupScreen: {fileID: 0} 190 | wiiUProfilerLibPath: 191 | actionOnDotNetUnhandledException: 1 192 | enableInternalProfiler: 0 193 | logObjCUncaughtExceptions: 1 194 | enableCrashReportAPI: 0 195 | locationUsageDescription: 196 | XboxTitleId: 197 | XboxImageXexPath: 198 | XboxSpaPath: 199 | XboxGenerateSpa: 0 200 | XboxDeployKinectResources: 0 201 | XboxSplashScreen: {fileID: 0} 202 | xboxEnableSpeech: 0 203 | xboxAdditionalTitleMemorySize: 0 204 | xboxDeployKinectHeadOrientation: 0 205 | xboxDeployKinectHeadPosition: 0 206 | ps3TitleConfigPath: 207 | ps3DLCConfigPath: 208 | ps3ThumbnailPath: 209 | ps3BackgroundPath: 210 | ps3SoundPath: 211 | ps3NPAgeRating: 12 212 | ps3TrophyCommId: 213 | ps3NpCommunicationPassphrase: 214 | ps3TrophyPackagePath: 215 | ps3BootCheckMaxSaveGameSizeKB: 128 216 | ps3TrophyCommSig: 217 | ps3SaveGameSlots: 1 218 | ps3TrialMode: 0 219 | ps3VideoMemoryForAudio: 0 220 | ps3EnableVerboseMemoryStats: 0 221 | ps3UseSPUForUmbra: 0 222 | ps3EnableMoveSupport: 1 223 | ps3DisableDolbyEncoding: 0 224 | ps4NPAgeRating: 12 225 | ps4NPTitleSecret: 226 | ps4NPTrophyPackPath: 227 | ps4ParentalLevel: 1 228 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 229 | ps4Category: 0 230 | ps4MasterVersion: 01.00 231 | ps4AppVersion: 01.00 232 | ps4AppType: 0 233 | ps4ParamSfxPath: 234 | ps4VideoOutPixelFormat: 0 235 | ps4VideoOutResolution: 4 236 | ps4PronunciationXMLPath: 237 | ps4PronunciationSIGPath: 238 | ps4BackgroundImagePath: 239 | ps4StartupImagePath: 240 | ps4SaveDataImagePath: 241 | ps4SdkOverride: 242 | ps4BGMPath: 243 | ps4ShareFilePath: 244 | ps4ShareOverlayImagePath: 245 | ps4PrivacyGuardImagePath: 246 | ps4NPtitleDatPath: 247 | ps4RemotePlayKeyAssignment: -1 248 | ps4RemotePlayKeyMappingDir: 249 | ps4EnterButtonAssignment: 1 250 | ps4ApplicationParam1: 0 251 | ps4ApplicationParam2: 0 252 | ps4ApplicationParam3: 0 253 | ps4ApplicationParam4: 0 254 | ps4DownloadDataSize: 0 255 | ps4GarlicHeapSize: 2048 256 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 257 | ps4pnSessions: 1 258 | ps4pnPresence: 1 259 | ps4pnFriends: 1 260 | ps4pnGameCustomData: 1 261 | playerPrefsSupport: 0 262 | ps4ReprojectionSupport: 0 263 | ps4UseAudio3dBackend: 0 264 | ps4Audio3dVirtualSpeakerCount: 14 265 | ps4attribUserManagement: 0 266 | ps4attribMoveSupport: 0 267 | ps4attrib3DSupport: 0 268 | ps4attribShareSupport: 0 269 | ps4IncludedModules: [] 270 | monoEnv: 271 | psp2Splashimage: {fileID: 0} 272 | psp2NPTrophyPackPath: 273 | psp2NPSupportGBMorGJP: 0 274 | psp2NPAgeRating: 12 275 | psp2NPTitleDatPath: 276 | psp2NPCommsID: 277 | psp2NPCommunicationsID: 278 | psp2NPCommsPassphrase: 279 | psp2NPCommsSig: 280 | psp2ParamSfxPath: 281 | psp2ManualPath: 282 | psp2LiveAreaGatePath: 283 | psp2LiveAreaBackroundPath: 284 | psp2LiveAreaPath: 285 | psp2LiveAreaTrialPath: 286 | psp2PatchChangeInfoPath: 287 | psp2PatchOriginalPackage: 288 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui 289 | psp2KeystoneFile: 290 | psp2MemoryExpansionMode: 0 291 | psp2DRMType: 0 292 | psp2StorageType: 0 293 | psp2MediaCapacity: 0 294 | psp2DLCConfigPath: 295 | psp2ThumbnailPath: 296 | psp2BackgroundPath: 297 | psp2SoundPath: 298 | psp2TrophyCommId: 299 | psp2TrophyPackagePath: 300 | psp2PackagedResourcesPath: 301 | psp2SaveDataQuota: 10240 302 | psp2ParentalLevel: 1 303 | psp2ShortTitle: Not Set 304 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 305 | psp2Category: 0 306 | psp2MasterVersion: 01.00 307 | psp2AppVersion: 01.00 308 | psp2TVBootMode: 0 309 | psp2EnterButtonAssignment: 2 310 | psp2TVDisableEmu: 0 311 | psp2AllowTwitterDialog: 1 312 | psp2Upgradable: 0 313 | psp2HealthWarning: 0 314 | psp2UseLibLocation: 0 315 | psp2InfoBarOnStartup: 0 316 | psp2InfoBarColor: 0 317 | psmSplashimage: {fileID: 0} 318 | spritePackerPolicy: 319 | scriptingDefineSymbols: {} 320 | metroPackageName: unitywebrtc 321 | metroPackageLogo: 322 | metroPackageLogo140: 323 | metroPackageLogo180: 324 | metroPackageLogo240: 325 | metroPackageVersion: 326 | metroCertificatePath: 327 | metroCertificatePassword: 328 | metroCertificateSubject: 329 | metroCertificateIssuer: 330 | metroCertificateNotAfter: 0000000000000000 331 | metroApplicationDescription: unitywebrtc 332 | metroStoreTileLogo80: 333 | metroStoreTileLogo: 334 | metroStoreTileLogo140: 335 | metroStoreTileLogo180: 336 | metroStoreTileWideLogo80: 337 | metroStoreTileWideLogo: 338 | metroStoreTileWideLogo140: 339 | metroStoreTileWideLogo180: 340 | metroStoreTileSmallLogo80: 341 | metroStoreTileSmallLogo: 342 | metroStoreTileSmallLogo140: 343 | metroStoreTileSmallLogo180: 344 | metroStoreSmallTile80: 345 | metroStoreSmallTile: 346 | metroStoreSmallTile140: 347 | metroStoreSmallTile180: 348 | metroStoreLargeTile80: 349 | metroStoreLargeTile: 350 | metroStoreLargeTile140: 351 | metroStoreLargeTile180: 352 | metroStoreSplashScreenImage: 353 | metroStoreSplashScreenImage140: 354 | metroStoreSplashScreenImage180: 355 | metroPhoneAppIcon: 356 | metroPhoneAppIcon140: 357 | metroPhoneAppIcon240: 358 | metroPhoneSmallTile: 359 | metroPhoneSmallTile140: 360 | metroPhoneSmallTile240: 361 | metroPhoneMediumTile: 362 | metroPhoneMediumTile140: 363 | metroPhoneMediumTile240: 364 | metroPhoneWideTile: 365 | metroPhoneWideTile140: 366 | metroPhoneWideTile240: 367 | metroPhoneSplashScreenImage: 368 | metroPhoneSplashScreenImage140: 369 | metroPhoneSplashScreenImage240: 370 | metroTileShortName: 371 | metroCommandLineArgsFile: 372 | metroTileShowName: 0 373 | metroMediumTileShowName: 0 374 | metroLargeTileShowName: 0 375 | metroWideTileShowName: 0 376 | metroDefaultTileSize: 1 377 | metroTileForegroundText: 1 378 | metroTileBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 379 | metroSplashScreenBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 380 | metroSplashScreenUseBackgroundColor: 0 381 | platformCapabilities: {} 382 | metroFTAName: 383 | metroFTAFileTypes: [] 384 | metroProtocolName: 385 | metroCompilationOverrides: 1 386 | blackberryDeviceAddress: 387 | blackberryDevicePassword: 388 | blackberryTokenPath: 389 | blackberryTokenExires: 390 | blackberryTokenAuthor: 391 | blackberryTokenAuthorId: 392 | blackberryCskPassword: 393 | blackberrySaveLogPath: 394 | blackberrySharedPermissions: 0 395 | blackberryCameraPermissions: 0 396 | blackberryGPSPermissions: 0 397 | blackberryDeviceIDPermissions: 0 398 | blackberryMicrophonePermissions: 0 399 | blackberryGamepadSupport: 0 400 | blackberryBuildId: 0 401 | blackberryLandscapeSplashScreen: {fileID: 0} 402 | blackberryPortraitSplashScreen: {fileID: 0} 403 | blackberrySquareSplashScreen: {fileID: 0} 404 | tizenProductDescription: 405 | tizenProductURL: 406 | tizenSigningProfileName: 407 | tizenGPSPermissions: 0 408 | tizenMicrophonePermissions: 0 409 | n3dsUseExtSaveData: 0 410 | n3dsCompressStaticMem: 1 411 | n3dsExtSaveDataNumber: 0x12345 412 | n3dsStackSize: 131072 413 | n3dsTargetPlatform: 2 414 | n3dsRegion: 7 415 | n3dsMediaSize: 0 416 | n3dsLogoStyle: 3 417 | n3dsTitle: GameName 418 | n3dsProductCode: 419 | n3dsApplicationId: 0xFF3FF 420 | stvDeviceAddress: 421 | stvProductDescription: 422 | stvProductAuthor: 423 | stvProductAuthorEmail: 424 | stvProductLink: 425 | stvProductCategory: 0 426 | XboxOneProductId: 427 | XboxOneUpdateKey: 428 | XboxOneSandboxId: 429 | XboxOneContentId: 430 | XboxOneTitleId: 431 | XboxOneSCId: 432 | XboxOneGameOsOverridePath: 433 | XboxOnePackagingOverridePath: 434 | XboxOneAppManifestOverridePath: 435 | XboxOnePackageEncryption: 0 436 | XboxOnePackageUpdateGranularity: 2 437 | XboxOneDescription: 438 | XboxOneIsContentPackage: 0 439 | XboxOneEnableGPUVariability: 0 440 | XboxOneSockets: {} 441 | XboxOneSplashScreen: {fileID: 0} 442 | XboxOneAllowedProductIds: [] 443 | XboxOnePersistentLocalStorageSize: 0 444 | intPropertyNames: 445 | - Android::ScriptingBackend 446 | - Metro::ScriptingBackend 447 | - Standalone::ScriptingBackend 448 | - WP8::ScriptingBackend 449 | - WebGL::ScriptingBackend 450 | - WebGL::audioCompressionFormat 451 | - WebGL::exceptionSupport 452 | - WebGL::memorySize 453 | - WebPlayer::ScriptingBackend 454 | - iOS::Architecture 455 | - iOS::EnableIncrementalBuildSupportForIl2cpp 456 | - iOS::ScriptingBackend 457 | Android::ScriptingBackend: 0 458 | Metro::ScriptingBackend: 2 459 | Standalone::ScriptingBackend: 0 460 | WP8::ScriptingBackend: 2 461 | WebGL::ScriptingBackend: 1 462 | WebGL::audioCompressionFormat: 4 463 | WebGL::exceptionSupport: 1 464 | WebGL::memorySize: 256 465 | WebPlayer::ScriptingBackend: 0 466 | iOS::Architecture: 2 467 | iOS::EnableIncrementalBuildSupportForIl2cpp: 0 468 | iOS::ScriptingBackend: 1 469 | boolPropertyNames: 470 | - WebGL::analyzeBuildSize 471 | - WebGL::dataCaching 472 | - WebGL::useEmbeddedResources 473 | - XboxOne::enus 474 | WebGL::analyzeBuildSize: 0 475 | WebGL::dataCaching: 0 476 | WebGL::useEmbeddedResources: 0 477 | XboxOne::enus: 1 478 | stringPropertyNames: 479 | - WebGL::emscriptenArgs 480 | - WebGL::template 481 | - additionalIl2CppArgs::additionalIl2CppArgs 482 | WebGL::emscriptenArgs: 483 | WebGL::template: APPLICATION:Default 484 | additionalIl2CppArgs::additionalIl2CppArgs: 485 | firstStreamedSceneWithResources: 0 486 | cloudProjectId: 487 | projectName: 488 | organizationId: 489 | cloudEnabled: 0 490 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.2.2f1 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 2 18 | shadowCascade2Split: .333333343 19 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 20 | blendWeights: 1 21 | textureQuality: 1 22 | anisotropicTextures: 0 23 | antiAliasing: 0 24 | softParticles: 0 25 | softVegetation: 0 26 | realtimeReflectionProbes: 0 27 | billboardsFaceCameraPosition: 0 28 | vSyncCount: 0 29 | lodBias: .300000012 30 | maximumLODLevel: 0 31 | particleRaycastBudget: 4 32 | excludedTargetPlatforms: [] 33 | - serializedVersion: 2 34 | name: Fast 35 | pixelLightCount: 0 36 | shadows: 0 37 | shadowResolution: 0 38 | shadowProjection: 1 39 | shadowCascades: 1 40 | shadowDistance: 20 41 | shadowNearPlaneOffset: 2 42 | shadowCascade2Split: .333333343 43 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 44 | blendWeights: 2 45 | textureQuality: 0 46 | anisotropicTextures: 0 47 | antiAliasing: 0 48 | softParticles: 0 49 | softVegetation: 0 50 | realtimeReflectionProbes: 0 51 | billboardsFaceCameraPosition: 0 52 | vSyncCount: 0 53 | lodBias: .400000006 54 | maximumLODLevel: 0 55 | particleRaycastBudget: 16 56 | excludedTargetPlatforms: [] 57 | - serializedVersion: 2 58 | name: Simple 59 | pixelLightCount: 1 60 | shadows: 1 61 | shadowResolution: 0 62 | shadowProjection: 1 63 | shadowCascades: 1 64 | shadowDistance: 20 65 | shadowNearPlaneOffset: 2 66 | shadowCascade2Split: .333333343 67 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 68 | blendWeights: 2 69 | textureQuality: 0 70 | anisotropicTextures: 1 71 | antiAliasing: 0 72 | softParticles: 0 73 | softVegetation: 0 74 | realtimeReflectionProbes: 0 75 | billboardsFaceCameraPosition: 0 76 | vSyncCount: 0 77 | lodBias: .699999988 78 | maximumLODLevel: 0 79 | particleRaycastBudget: 64 80 | excludedTargetPlatforms: [] 81 | - serializedVersion: 2 82 | name: Good 83 | pixelLightCount: 2 84 | shadows: 2 85 | shadowResolution: 1 86 | shadowProjection: 1 87 | shadowCascades: 2 88 | shadowDistance: 40 89 | shadowNearPlaneOffset: 2 90 | shadowCascade2Split: .333333343 91 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 92 | blendWeights: 2 93 | textureQuality: 0 94 | anisotropicTextures: 1 95 | antiAliasing: 0 96 | softParticles: 0 97 | softVegetation: 1 98 | realtimeReflectionProbes: 1 99 | billboardsFaceCameraPosition: 1 100 | vSyncCount: 1 101 | lodBias: 1 102 | maximumLODLevel: 0 103 | particleRaycastBudget: 256 104 | excludedTargetPlatforms: [] 105 | - serializedVersion: 2 106 | name: Beautiful 107 | pixelLightCount: 3 108 | shadows: 2 109 | shadowResolution: 2 110 | shadowProjection: 1 111 | shadowCascades: 2 112 | shadowDistance: 70 113 | shadowNearPlaneOffset: 2 114 | shadowCascade2Split: .333333343 115 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 116 | blendWeights: 4 117 | textureQuality: 0 118 | anisotropicTextures: 2 119 | antiAliasing: 2 120 | softParticles: 1 121 | softVegetation: 1 122 | realtimeReflectionProbes: 1 123 | billboardsFaceCameraPosition: 1 124 | vSyncCount: 1 125 | lodBias: 1.5 126 | maximumLODLevel: 0 127 | particleRaycastBudget: 1024 128 | excludedTargetPlatforms: [] 129 | - serializedVersion: 2 130 | name: Fantastic 131 | pixelLightCount: 4 132 | shadows: 2 133 | shadowResolution: 2 134 | shadowProjection: 1 135 | shadowCascades: 4 136 | shadowDistance: 150 137 | shadowNearPlaneOffset: 2 138 | shadowCascade2Split: .333333343 139 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 140 | blendWeights: 4 141 | textureQuality: 0 142 | anisotropicTextures: 2 143 | antiAliasing: 2 144 | softParticles: 1 145 | softVegetation: 1 146 | realtimeReflectionProbes: 1 147 | billboardsFaceCameraPosition: 1 148 | vSyncCount: 1 149 | lodBias: 2 150 | maximumLODLevel: 0 151 | particleRaycastBudget: 4096 152 | excludedTargetPlatforms: [] 153 | m_PerPlatformDefaultQuality: 154 | Android: 2 155 | BlackBerry: 2 156 | GLES Emulation: 5 157 | Nintendo 3DS: 5 158 | PS3: 5 159 | PS4: 5 160 | PSM: 5 161 | PSP2: 2 162 | Samsung TV: 2 163 | Standalone: 5 164 | Tizen: 2 165 | WP8: 5 166 | Web: 5 167 | WebGL: 3 168 | Wii U: 5 169 | Windows Store Apps: 5 170 | XBOX360: 5 171 | XboxOne: 5 172 | iPhone: 2 173 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: .0625 7 | Maximum Allowed Timestep: .333333343 8 | m_TimeScale: 1 9 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/UnityAdsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!292 &1 4 | UnityAdsSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_InitializeOnStartup: 1 8 | m_TestMode: 0 9 | m_EnabledPlatforms: 4294967295 10 | m_IosGameId: 11 | m_AndroidGameId: 12 | -------------------------------------------------------------------------------- /unitywebrtc/ProjectSettings/UnityAnalyticsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!303 &1 4 | UnityAnalyticsManager: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_InitializeOnStartup: 1 8 | m_TestMode: 0 9 | m_TestEventUrl: 10 | m_TestConfigUrl: 11 | --------------------------------------------------------------------------------