├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── app ├── App_Resources │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── app.gradle │ │ ├── drawable-hdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-ldpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-mdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-nodpi │ │ │ └── splash_screen.xml │ │ ├── drawable-xhdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-xxhdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-xxxhdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── playstore-icon.png │ │ ├── values-v21 │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ └── iOS │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── iTunesArtwork.png │ │ │ ├── iTunesArtwork@2x.png │ │ │ ├── icon-120.png │ │ │ ├── icon-29.png │ │ │ ├── icon-29@2x.png │ │ │ ├── icon-29@3x.png │ │ │ ├── icon-40.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-40@3x.png │ │ │ ├── icon-50.png │ │ │ ├── icon-50@2x.png │ │ │ ├── icon-57.png │ │ │ ├── icon-57@2x.png │ │ │ ├── icon-57@3x.png │ │ │ ├── icon-60.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-60@3x.png │ │ │ ├── icon-72.png │ │ │ ├── icon-72@2x.png │ │ │ ├── icon-72@3x.png │ │ │ ├── icon-76.png │ │ │ ├── icon-76@2x.png │ │ │ ├── icon-76@3x.png │ │ │ ├── icon-83.5@2x.png │ │ │ ├── icon-Small.png │ │ │ ├── icon-Small@2x.png │ │ │ ├── icon-Small@3x.png │ │ │ └── icon.png │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ ├── Contents.json │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-667h@2x.png │ │ │ ├── Default-736h@3x.png │ │ │ ├── Default-Landscape.png │ │ │ ├── Default-Landscape@2x.png │ │ │ ├── Default-Landscape@3x.png │ │ │ ├── Default-Portrait.png │ │ │ ├── Default-Portrait@2x.png │ │ │ ├── Default.png │ │ │ └── Default@2x.png │ │ ├── LaunchScreen.AspectFill.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchScreen-AspectFill.png │ │ │ └── LaunchScreen-AspectFill@2x.png │ │ └── LaunchScreen.Center.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchScreen-Center.png │ │ │ └── LaunchScreen-Center@2x.png │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── build.xcconfig │ │ └── logo.png ├── README.md ├── app.css ├── app.js ├── fonts │ └── fontawesome-webfont.ttf ├── images │ └── .gitkeep ├── package.json ├── platform.android.css ├── platform.ios.css ├── prototypes │ └── numbers.js ├── services │ ├── league.js │ ├── screeps.js │ └── session.js ├── shared │ ├── navtools.js │ └── widgets │ │ ├── header.xml │ │ └── navigation.xml ├── views │ ├── about │ │ ├── about.css │ │ ├── about.js │ │ └── about.xml │ ├── alliance │ │ ├── alliance.css │ │ ├── alliance.js │ │ ├── alliance.xml │ │ ├── members.js │ │ └── members.xml │ ├── alliances │ │ ├── alliances.css │ │ ├── alliances.js │ │ └── alliances.xml │ ├── category_template │ │ ├── template.css │ │ ├── template.js │ │ └── template.xml │ ├── console │ │ ├── console.css │ │ ├── console.js │ │ └── console.xml │ ├── login │ │ ├── login.css │ │ ├── login.js │ │ └── login.xml │ ├── messages │ │ ├── conversation.css │ │ ├── conversation.js │ │ ├── conversation.xml │ │ ├── messages.css │ │ ├── messages.js │ │ └── messages.xml │ ├── orders │ │ ├── orders.css │ │ ├── orders.js │ │ └── orders.xml │ ├── profile │ │ ├── profile.css │ │ ├── profile.js │ │ └── profile.xml │ ├── server │ │ ├── server.css │ │ ├── server.js │ │ └── server.xml │ └── wallet │ │ ├── transaction.css │ │ ├── transaction.js │ │ ├── transaction.xml │ │ ├── wallet.css │ │ ├── wallet.js │ │ └── wallet.xml └── www │ └── lib │ ├── es6-promise.min.js │ ├── nativescript-canvas-interface.js │ └── nativescript-webview-interface.js ├── docs └── Roadmap.md ├── hooks ├── after-prepare │ └── nativescript-dev-android-snapshot.js └── before-prepare │ ├── nativescript-dev-android-snapshot.js │ └── nativescript-nodeify.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | /platforms 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # nyc test coverage 20 | .nyc_output 21 | 22 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 23 | .grunt 24 | 25 | # node-waf configuration 26 | .lock-wscript 27 | 28 | # Compiled binary addons (http://nodejs.org/api/addons.html) 29 | build/Release 30 | 31 | # Dependency directories 32 | node_modules 33 | jspm_packages 34 | 35 | # Optional npm cache directory 36 | .npm 37 | 38 | # Optional REPL history 39 | .node_repl_history 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Robert Hafner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | SHELL:=/bin/bash 3 | ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 4 | 5 | .PHONY: build build_android build_ios clean clean_android clean_ios clean_dependencies run_android run_ios 6 | 7 | all: install 8 | 9 | refresh: clean install 10 | 11 | install: 12 | yes "" | tns install 13 | 14 | build: build_android build_ios 15 | 16 | build_android: 17 | tns build add android 18 | 19 | build_ios: 20 | tns build add ios 21 | 22 | run_android: 23 | tns run android 24 | 25 | run_ios: 26 | tns run ios 27 | 28 | clean: clean_dependencies clean_platforms 29 | 30 | clean_platforms: 31 | if [ -d $(ROOT_DIR)/platforms ]; then \ 32 | rm -rf $(ROOT_DIR)/platforms; \ 33 | fi; 34 | 35 | clean_android: 36 | tns platform remove android || true 37 | tns platform add android 38 | 39 | clean_ios: 40 | tns platform remove ios || true 41 | tns platform add ios 42 | 43 | clean_dependencies: 44 | if [ -d $(ROOT_DIR)/node_modules ]; then \ 45 | rm -rf $(ROOT_DIR)/node_modules; \ 46 | fi; 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spawn1 2 | 3 | The Unofficial Mobile Client for Screeps. 4 | 5 | ## Technology 6 | 7 | * NativeScript - code in javascript and compile down to native apps. 8 | * Screeps API - since this is a Screeps client it does pull data down from Screeps. 9 | * League of Automated Nations - data is also pulled in from this site. 10 | 11 | 12 | ## Setup 13 | 14 | 1. [NativeScript Quick Setup](https://docs.nativescript.org/start/quick-setup). 15 | 2. `make` 16 | 3. `tns run ios` or `tns run android` to compile and run. 17 | 18 | 19 | ## Roadmap 20 | 21 | Current plans are outlined on the [Roadmap](docs/Roadmap.md). 22 | -------------------------------------------------------------------------------- /app/App_Resources/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/App_Resources/Android/app.gradle: -------------------------------------------------------------------------------- 1 | // Add your native dependencies here: 2 | 3 | // Uncomment to add recyclerview-v7 dependency 4 | //dependencies { 5 | // compile 'com.android.support:recyclerview-v7:+' 6 | //} 7 | 8 | android { 9 | defaultConfig { 10 | generatedDensities = [] 11 | applicationId = "org.screepers.Spawn1" 12 | 13 | //override supported platforms 14 | // ndk { 15 | // abiFilters.clear() 16 | // abiFilters "armeabi-v7a" 17 | // } 18 | 19 | } 20 | aaptOptions { 21 | additionalParameters "--no-version-vectors" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-hdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-hdpi/background.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-hdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-hdpi/logo.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-ldpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-ldpi/background.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-ldpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-ldpi/logo.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-mdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-mdpi/background.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-mdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-mdpi/logo.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-nodpi/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xhdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xhdpi/background.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xhdpi/logo.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xxhdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xxhdpi/background.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xxhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xxhdpi/logo.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xxxhdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xxxhdpi/background.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/drawable-xxxhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/drawable-xxxhdpi/logo.png -------------------------------------------------------------------------------- /app/App_Resources/Android/playstore-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/Android/playstore-icon.png -------------------------------------------------------------------------------- /app/App_Resources/Android/values-v21/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3d5afe 4 | -------------------------------------------------------------------------------- /app/App_Resources/Android/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 14 | 15 | 16 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /app/App_Resources/Android/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F5F5F5 4 | #757575 5 | #33B5E5 6 | #272734 7 | -------------------------------------------------------------------------------- /app/App_Resources/Android/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | 21 | 22 | 23 | 31 | 32 | 34 | 35 | 36 | 42 | 43 | 45 | 46 | -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "icon-29.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "icon-29@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon-29@3x.png", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "icon-40@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon-40@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "57x57", 35 | "idiom" : "iphone", 36 | "filename" : "icon-57.png", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "size" : "57x57", 41 | "idiom" : "iphone", 42 | "filename" : "icon-57@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "icon-57@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "icon-60.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "icon-60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "icon-60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "icon-29.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "icon-29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "icon-40.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "icon-40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "50x50", 95 | "idiom" : "ipad", 96 | "filename" : "icon-50.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "50x50", 101 | "idiom" : "ipad", 102 | "filename" : "icon-50@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "72x72", 107 | "idiom" : "ipad", 108 | "filename" : "icon-72.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "72x72", 113 | "idiom" : "ipad", 114 | "filename" : "icon-72@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "icon-72@3x.png", 121 | "scale" : "3x" 122 | }, 123 | { 124 | "size" : "76x76", 125 | "idiom" : "ipad", 126 | "filename" : "icon-76.png", 127 | "scale" : "1x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "icon-76@2x.png", 133 | "scale" : "2x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "icon-76@3x.png", 139 | "scale" : "3x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "icon-83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "size" : "120x120", 149 | "idiom" : "ipad", 150 | "filename" : "icon120.png", 151 | "scale" : "1x" 152 | }, 153 | 154 | ], 155 | "info" : { 156 | "version" : 1, 157 | "author" : "xcode" 158 | } 159 | } -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-120.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "736h", 7 | "filename" : "Default-736h@3x.png", 8 | "minimum-system-version" : "8.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "extent" : "full-screen", 14 | "idiom" : "iphone", 15 | "subtype" : "736h", 16 | "filename" : "Default-Landscape@3x.png", 17 | "minimum-system-version" : "8.0", 18 | "orientation" : "landscape", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "extent" : "full-screen", 23 | "idiom" : "iphone", 24 | "subtype" : "667h", 25 | "filename" : "Default-667h@2x.png", 26 | "minimum-system-version" : "8.0", 27 | "orientation" : "portrait", 28 | "scale" : "2x" 29 | }, 30 | { 31 | "orientation" : "portrait", 32 | "idiom" : "iphone", 33 | "filename" : "Default@2x.png", 34 | "extent" : "full-screen", 35 | "minimum-system-version" : "7.0", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "extent" : "full-screen", 40 | "idiom" : "iphone", 41 | "subtype" : "retina4", 42 | "filename" : "Default-568h@2x.png", 43 | "minimum-system-version" : "7.0", 44 | "orientation" : "portrait", 45 | "scale" : "2x" 46 | }, 47 | { 48 | "orientation" : "portrait", 49 | "idiom" : "ipad", 50 | "filename" : "Default-Portrait.png", 51 | "extent" : "full-screen", 52 | "minimum-system-version" : "7.0", 53 | "scale" : "1x" 54 | }, 55 | { 56 | "orientation" : "landscape", 57 | "idiom" : "ipad", 58 | "filename" : "Default-Landscape.png", 59 | "extent" : "full-screen", 60 | "minimum-system-version" : "7.0", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "orientation" : "portrait", 65 | "idiom" : "ipad", 66 | "filename" : "Default-Portrait@2x.png", 67 | "extent" : "full-screen", 68 | "minimum-system-version" : "7.0", 69 | "scale" : "2x" 70 | }, 71 | { 72 | "orientation" : "landscape", 73 | "idiom" : "ipad", 74 | "filename" : "Default-Landscape@2x.png", 75 | "extent" : "full-screen", 76 | "minimum-system-version" : "7.0", 77 | "scale" : "2x" 78 | }, 79 | { 80 | "orientation" : "portrait", 81 | "idiom" : "iphone", 82 | "filename" : "Default.png", 83 | "extent" : "full-screen", 84 | "scale" : "1x" 85 | }, 86 | { 87 | "orientation" : "portrait", 88 | "idiom" : "iphone", 89 | "filename" : "Default@2x.png", 90 | "extent" : "full-screen", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "orientation" : "portrait", 95 | "idiom" : "iphone", 96 | "filename" : "Default-568h@2x.png", 97 | "extent" : "full-screen", 98 | "subtype" : "retina4", 99 | "scale" : "2x" 100 | }, 101 | { 102 | "orientation" : "portrait", 103 | "idiom" : "ipad", 104 | "extent" : "to-status-bar", 105 | "scale" : "1x" 106 | }, 107 | { 108 | "orientation" : "portrait", 109 | "idiom" : "ipad", 110 | "filename" : "Default-Portrait.png", 111 | "extent" : "full-screen", 112 | "scale" : "1x" 113 | }, 114 | { 115 | "orientation" : "landscape", 116 | "idiom" : "ipad", 117 | "extent" : "to-status-bar", 118 | "scale" : "1x" 119 | }, 120 | { 121 | "orientation" : "landscape", 122 | "idiom" : "ipad", 123 | "filename" : "Default-Landscape.png", 124 | "extent" : "full-screen", 125 | "scale" : "1x" 126 | }, 127 | { 128 | "orientation" : "portrait", 129 | "idiom" : "ipad", 130 | "extent" : "to-status-bar", 131 | "scale" : "2x" 132 | }, 133 | { 134 | "orientation" : "portrait", 135 | "idiom" : "ipad", 136 | "filename" : "Default-Portrait@2x.png", 137 | "extent" : "full-screen", 138 | "scale" : "2x" 139 | }, 140 | { 141 | "orientation" : "landscape", 142 | "idiom" : "ipad", 143 | "extent" : "to-status-bar", 144 | "scale" : "2x" 145 | }, 146 | { 147 | "orientation" : "landscape", 148 | "idiom" : "ipad", 149 | "filename" : "Default-Landscape@2x.png", 150 | "extent" : "full-screen", 151 | "scale" : "2x" 152 | } 153 | ], 154 | "info" : { 155 | "version" : 1, 156 | "author" : "xcode" 157 | } 158 | } -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchScreen-AspectFill.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchScreen-AspectFill@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchScreen-Center.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchScreen-Center@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png -------------------------------------------------------------------------------- /app/App_Resources/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Spawn1 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiresFullScreen 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | LSApplicationQueriesSchemes 47 | 48 | slack 49 | 50 | NSAppTransportSecurity 51 | 52 | NSExceptionDomains 53 | 54 | screeps.com 55 | 56 | 57 | NSIncludesSubdomains 58 | 59 | 60 | NSTemporaryExceptionAllowsInsecureHTTPLoads 61 | 62 | 63 | NSTemporaryExceptionMinimumTLSVersion 64 | TLSv1.1 65 | 66 | leagueofautomatednations.com 67 | 68 | 69 | NSIncludesSubdomains 70 | 71 | 72 | NSTemporaryExceptionAllowsInsecureHTTPLoads 73 | 74 | 75 | NSTemporaryExceptionMinimumTLSVersion 76 | TLSv1.1 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /app/App_Resources/iOS/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 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 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/App_Resources/iOS/build.xcconfig: -------------------------------------------------------------------------------- 1 | // You can add custom settings here 2 | // for example you can uncomment the following line to force distribution code signing 3 | // CODE_SIGN_IDENTITY = iPhone Distribution 4 | // To build for device with Xcode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html 5 | // DEVELOPMENT_TEAM = YOUR_TEAM_ID; 6 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 7 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 8 | -------------------------------------------------------------------------------- /app/App_Resources/iOS/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/App_Resources/iOS/logo.png -------------------------------------------------------------------------------- /app/README.md: -------------------------------------------------------------------------------- 1 | # NativeScript Tutorial JavaScript Template 2 | 3 | This repo serves as the starting point for NativeScript’s [JavaScript Getting Started Guide](https://docs.nativescript.org/tutorial/chapter-0). 4 | 5 | Please file any issues with this template on the [NativeScript/docs repository](https://github.com/nativescript/docs), which is where the tutorial content lives. -------------------------------------------------------------------------------- /app/app.css: -------------------------------------------------------------------------------- 1 | 2 | @import url('~/platform.css'); 3 | 4 | 5 | /* #243044 */ 6 | /* #556278 */ 7 | /* #3B485D */ 8 | /* #162339 */ 9 | /* #0A1527 */ 10 | /* #FF404B */ 11 | 12 | /* Your CSS goes here */ 13 | 14 | Page { 15 | background-color: #243044; 16 | color: white; 17 | font-size: 17; 18 | } 19 | 20 | ListView { 21 | background-color: #243044; 22 | color: white; 23 | } 24 | 25 | .list-view { 26 | background-color: #243044; 27 | color: white; 28 | } 29 | 30 | TextField { 31 | margin: 10; 32 | padding: 10; 33 | placeholder-color: #556278; 34 | } 35 | 36 | 37 | actionBar { 38 | color: black; 39 | } 40 | 41 | Image { 42 | margin-top: 20; 43 | margin-left: 0; 44 | margin-right: 0; 45 | margin-bottom: 80; 46 | } 47 | Button { 48 | margin: 10; 49 | padding: 10; 50 | } 51 | 52 | .drawer-content { 53 | background-color: #556278; 54 | color: white; 55 | padding-top: 20; 56 | } 57 | .drawer-content Label { 58 | font-size: 20; 59 | margin: 10 0 15 25; 60 | } 61 | 62 | 63 | Label { 64 | margin: 10; 65 | } 66 | 67 | .line-through { 68 | text-decoration: line-through; 69 | } 70 | 71 | .h1 { 72 | font-size: 36; 73 | margin-bottom: 10; } 74 | 75 | .h2 { 76 | font-size: 30; 77 | margin: 10 0 10 0; } 78 | 79 | .h3 { 80 | font-size: 24; 81 | margin: 10 0 10 0; } 82 | 83 | .h4 { 84 | font-size: 18; 85 | margin: 10 0 10 0; } 86 | 87 | .h5 { 88 | font-size: 14; 89 | margin: 10 0 10 0; } 90 | 91 | .h6 { 92 | font-size: 12; 93 | margin: 10 0 10 0; } 94 | 95 | .p { 96 | font-size: 14; 97 | margin: 0 0 10 0; } 98 | 99 | .button { 100 | padding: 10 12 10 10; 101 | min-width: 52; 102 | border-radius: 2; } 103 | .button .button-accent { 104 | background-color: #FF404B; 105 | color: #ffffff; } 106 | .button .button-accent .button-outline { 107 | background-color: #ffffff; 108 | color: #FF404B; 109 | border-color: #FF404B; 110 | border-width: 1; } 111 | 112 | .button-full { 113 | padding: 0; } 114 | 115 | .button-small { 116 | padding: 2 4 1 4; 117 | min-width: 28; 118 | min-height: 30; 119 | font-size: 12; } 120 | 121 | .button-large { 122 | padding: 0 16 0 16; 123 | min-width: 68; 124 | min-height: 59; 125 | font-size: 20; } 126 | 127 | .button-light { 128 | background-color: #ffffff; 129 | color: #FF404B; 130 | border-color: #b2b2b2; 131 | border-width: 1; } 132 | 133 | .button-dark { 134 | background-color: #243044; 135 | color: #ffffff; } 136 | .button-dark .button-outline { 137 | color: #243044; 138 | border-color: #243044; 139 | border-width: 1; } 140 | 141 | 142 | .listview { 143 | background-color: #243044 144 | color: white; } 145 | .listview .item { 146 | padding: 10 10 10 10; 147 | font-size: 16; 148 | background-color: #243044; 149 | color: white; } 150 | .listview .item .h2 { 151 | margin: 0; 152 | margin: 0; 153 | font-size: 20; } 154 | .listview .item .p { 155 | font-size: 14; 156 | color: white; 157 | margin: 0; } 158 | 159 | .listview-inset { 160 | margin: 10; 161 | border-width: 1; 162 | border-color: #243044; 163 | border-radius: 10; } 164 | 165 | .item-avatar image { 166 | border-radius: 25; 167 | width: 50; 168 | height: 50; } 169 | 170 | .item-avatar stacklayout, .item-thumbnail stacklayout { 171 | padding-left: 16; } 172 | 173 | .form { 174 | margin: 0 0 20 0; 175 | padding: 0; } 176 | .form .button { 177 | margin: 0 0 0 10; 178 | padding: 0; } 179 | .form switch { 180 | margin-right: 16; } 181 | .form .form-item { 182 | padding: 10 16 10 16; } 183 | .form .input { 184 | padding-top: 2; } 185 | .form .input-inset { 186 | background-color: #EEEEEE; 187 | border-radius: 2; 188 | padding: 8; } 189 | .form .input-label { 190 | font-size: 18; 191 | padding: 4 0 5 0; 192 | color: #444; } 193 | 194 | .form-inset { 195 | margin: 10; 196 | border-width: 1; 197 | border-color: #DDDDDD; } 198 | 199 | .switch-accent { 200 | background-color: #FF404B; } 201 | 202 | .switch-dark { 203 | background-color: #243044; } 204 | 205 | .slider-light { 206 | background-color: #ffffff; } 207 | 208 | .slider-accent { 209 | background-color: #FF404B; } 210 | 211 | .slider-dark { 212 | background-color: #243044; } 213 | 214 | .segmented-bar { 215 | height: 50; } 216 | .segmented-bar .segmnted-bar-light { 217 | background-color: #ffffff; } 218 | .segmented-bar .segmented-bar-accent { 219 | background-color: #FF404B; 220 | color: #ffffff; } 221 | .segmented-bar .segmented-bar-dark { 222 | background-color: #243044; 223 | color: #ffffff; } 224 | 225 | 226 | .fa { 227 | font-family: 'FontAwesome', 'fontawesome-webfont'; } 228 | 229 | .fa-large { 230 | font-family: 'FontAwesome', 'fontawesome-webfont'; 231 | font-size: 26; } 232 | 233 | .padding { 234 | padding: 10; } 235 | 236 | .edges { 237 | margin-left: 10; 238 | margin-right: 10; } 239 | 240 | .left { 241 | horizontal-align: left; 242 | text-align: left; } 243 | 244 | .right { 245 | text-align: right; 246 | horizontal-align: right; } 247 | 248 | .center { 249 | horizontal-align: center; 250 | text-align: center; } 251 | 252 | .hr { 253 | height: 1; 254 | background-color: #CDCDCD; } 255 | 256 | .debug { 257 | border-width: 1; 258 | border-color: red; } 259 | 260 | .datetime { 261 | font-style: italic; 262 | font-size: 10; 263 | margin: 0 0 10 0; 264 | } 265 | 266 | -------------------------------------------------------------------------------- /app/app.js: -------------------------------------------------------------------------------- 1 | var application = require("application"); 2 | require("nativescript-nodeify"); 3 | require("./prototypes/numbers.js") 4 | require("./services/league.js") 5 | var ScreepsAPI = require("./services/screeps.js") 6 | var imageCache = require("nativescript-web-image-cache"); 7 | 8 | // Refresh cache when app is loaded. 9 | 10 | application.on(application.launchEvent, function (args) { 11 | if (application.android) { 12 | imageCache.initialize(); 13 | imageCache.clearCache(); 14 | } 15 | 16 | var ScreepsSocket = ScreepsAPI.get_web_socket() 17 | if(!!ScreepsSocket.subscriptions && ScreepsSocket.subscriptions.length > 0) { 18 | ScreepsSocket.connect() 19 | } 20 | }) 21 | 22 | application.on(application.suspendEvent, function (args) { 23 | ScreepsAPI.get_web_socket().disconnect() 24 | }) 25 | 26 | application.on(application.resumeEvent, function (args) { 27 | var ScreepsSocket = ScreepsAPI.get_web_socket() 28 | if(!!ScreepsSocket.subscriptions && ScreepsSocket.subscriptions.length > 0) { 29 | ScreepsSocket.connect() 30 | } 31 | }) 32 | 33 | application.on(application.exitEvent, function (args) { 34 | ScreepsAPI.get_web_socket().disconnect() 35 | }) 36 | 37 | 38 | application.start({ moduleName: "views/login/login" }); 39 | -------------------------------------------------------------------------------- /app/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /app/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/images/.gitkeep -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "app.js", 3 | "name": "spawn1", 4 | "version": "1.0.1" 5 | } -------------------------------------------------------------------------------- /app/platform.android.css: -------------------------------------------------------------------------------- 1 | /* From platform.android.css */ 2 | .link { 3 | background-color: transparent; 4 | } 5 | -------------------------------------------------------------------------------- /app/platform.ios.css: -------------------------------------------------------------------------------- 1 | /* From platform.ios.css */ 2 | .link { 3 | border-width: 0; 4 | } 5 | -------------------------------------------------------------------------------- /app/prototypes/numbers.js: -------------------------------------------------------------------------------- 1 | 2 | Number.prototype.toAbbreviated = function() { 3 | 4 | if(this > Math.pow(10, 12)) { 5 | var divisor = Math.pow(10, 12) 6 | var unit = 'T' 7 | } else if(this > Math.pow(10, 9)) { 8 | var divisor = Math.pow(10, 9) 9 | var unit = 'B' 10 | } else if(this > Math.pow(10, 6)) { 11 | var divisor = Math.pow(10, 6) 12 | var unit = 'M' 13 | } else if(this > Math.pow(10, 3)) { 14 | var divisor = Math.pow(10, 3) 15 | var unit = 'K' 16 | } else { 17 | var divisor = 1 18 | var unit = '' 19 | } 20 | 21 | return ((this / divisor).toPrecision(3)) + unit 22 | } 23 | -------------------------------------------------------------------------------- /app/services/league.js: -------------------------------------------------------------------------------- 1 | var applicationSettings = require("application-settings"); 2 | var timer = require("timer"); 3 | 4 | var leagueurl = 'http://www.leagueofautomatednations.com/' 5 | 6 | class League { 7 | constructor() { 8 | this.users = {} 9 | this.alliances = {} 10 | this.loadAllianceData() 11 | var that = this 12 | 13 | // Update every 30 minutes 14 | timer.setInterval(function(){ 15 | that.loadAllianceData() 16 | }, (1000 * 60 * 30)) 17 | } 18 | 19 | loadAllianceData() { 20 | // Load from application settings if it's available. This way it's possible 21 | // to browser alliance data without an internet connection. 22 | this.alliances = JSON.parse(applicationSettings.getString('league_alliance_data', '{}')) 23 | this.users = JSON.parse(applicationSettings.getString('league_user_data', '{}')) 24 | 25 | console.log('Loading alliance data from ' + leagueurl + 'alliances.js') 26 | var that = this 27 | return fetch(leagueurl + "alliances.js") 28 | .then(response => { 29 | if(!response.ok) { 30 | throw new Error() 31 | } 32 | return response.json() 33 | }) 34 | .then(function (r) { 35 | that.alliances = r 36 | that.users = {} 37 | for(var alliance in that.alliances) { 38 | 39 | if(that.alliances[alliance]['slack_channel']) { 40 | that.alliances[alliance]['slackurl'] = 'slack://channel?team=T0HJCPP9T' 41 | if(that.alliances[alliance]['slack_channelid']) { 42 | that.alliances[alliance]['slackurl'] += '&id=' + that.alliances[alliance]['slack_channelid'] 43 | } 44 | } 45 | 46 | if(that.alliances[alliance]['logo']) { 47 | that.alliances[alliance]['logo'] = leagueurl + 'obj/' + that.alliances[alliance]['logo'] 48 | } else { 49 | that.alliances[alliance]['logo'] = leagueurl + 'static/img/leaguelogo.png' 50 | } 51 | 52 | that.alliances[alliance].memberCount = that.alliances[alliance].members.length 53 | that.alliances[alliance].memberObjects = [] 54 | 55 | that.alliances[alliance].members.sort(function(a,b){ 56 | var textA = a.toUpperCase(); 57 | var textB = b.toUpperCase(); 58 | return (textA < textB) ? -1 : (textA > textB) ? 1 : 0; 59 | }) 60 | 61 | for(var user of that.alliances[alliance].members) { 62 | that.alliances[alliance].memberObjects.push({'name':user}) 63 | that.users[user] = alliance 64 | } 65 | } 66 | 67 | 68 | applicationSettings.setString('league_alliance_data', JSON.stringify(that.alliances)) 69 | applicationSettings.setString('league_user_data', JSON.stringify(that.users)) 70 | 71 | }) 72 | .catch(function(err){ 73 | console.log(err.message) 74 | console.log(err.stack) 75 | }) 76 | } 77 | 78 | getUserAlliance(user) { 79 | return !!this.users[user] ? this.users[user] : false 80 | } 81 | 82 | getAlliance(alliance) { 83 | return !!this.alliances[alliance] ? this.alliances[alliance] : false 84 | } 85 | 86 | getAllianceList() { 87 | return Object.keys(this.alliances()) 88 | } 89 | 90 | getAllianceData() { 91 | return Object.values(this.alliances) 92 | } 93 | 94 | getBadgeUrl(username, alliance=true) { 95 | var prefix = alliance ? 'alliances/' : 'users/' 96 | return leagueurl + 'badges/' + prefix + username + '.png' 97 | } 98 | } 99 | 100 | module.exports = new League() 101 | -------------------------------------------------------------------------------- /app/services/screeps.js: -------------------------------------------------------------------------------- 1 | require('nativescript-websockets'); 2 | 3 | // Time- in milliseconds- after which we reauthenticate. 4 | const authentication_timeout = 45000 5 | 6 | class ScreepsAPI { 7 | 8 | set username (v) { 9 | this.opts.username = v 10 | } 11 | 12 | set password (v) { 13 | this.opts.password = v 14 | } 15 | 16 | constructor(opts) { 17 | this.opts = opts 18 | this.token = false 19 | 20 | if(!this.opts.host) { 21 | this.opts.host = opts.ptr ? 'screeps.com/ptr/' : 'screeps.com/' 22 | } 23 | this.opts.prefix = this.opts.insecure ? 'http://' : 'https://' 24 | } 25 | 26 | authcheck() { 27 | var lastcall = this.lastcall || 1 28 | this.lastcall = (new Date()).getTime() 29 | 30 | if(!this.token || (this.lastcall - lastcall) > authentication_timeout) { 31 | return this.auth() 32 | } 33 | 34 | return Promise.resolve(true) 35 | } 36 | 37 | get_web_socket() { 38 | if(!this.socket) { 39 | this.socket = new ScreepsSocket(this, this.opts) 40 | } 41 | return this.socket 42 | } 43 | 44 | reset() { 45 | delete this.opts.username 46 | delete this.opts.password 47 | this.token = false 48 | } 49 | 50 | req(endpoint, method, body, contenttype) { 51 | var that = this 52 | var request_options = { 53 | method: method, 54 | headers: { 55 | 'X-Token': this.token, 56 | 'X-Username': this.token, 57 | 'Accept': 'application/json, application/xml, text/plain, text/html, *.*', 58 | } 59 | } 60 | 61 | if(contenttype) { 62 | request_options['headers']['Content-Type'] = contenttype 63 | } 64 | 65 | if(body) { 66 | request_options['body'] = body 67 | } 68 | var base = this.opts.prefix + this.opts.host + 'api/' 69 | console.log(base + endpoint) 70 | var that = this 71 | return fetch(base + endpoint, request_options) 72 | 73 | // Update authentication token and procress json response. 74 | // @todo deal with compressed data. 75 | .then(function(response) { 76 | if(!response.ok) { 77 | if(!!that.token && response.status == '403') { 78 | that.token = false 79 | } 80 | throw new Error(response.status + ': ' + response.statusText) 81 | } 82 | if(!!response.headers.has('X-Token')) { 83 | that.token = response.headers.get('X-Token') 84 | } 85 | that.lastcall = (new Date()).getTime() 86 | return response.json() 87 | }) 88 | .then(function(data){ 89 | if(data['token']) { 90 | that.token = data['token'] 91 | } 92 | return data 93 | }) 94 | } 95 | 96 | get(endpoint, args) { 97 | var that = this 98 | return this.authcheck().then(function(){ 99 | if(!!args) { 100 | endpoint += '?' + Object.keys(args).map(function(key) { 101 | return [key, args[key]].map(encodeURIComponent).join("="); 102 | }).join("&"); 103 | } 104 | return that.req(endpoint, 'GET') 105 | }) 106 | } 107 | 108 | post(endpoint, args) { 109 | var that = this 110 | return this.authcheck().then(function(){ 111 | console.log(endpoint) 112 | if(endpoint != 'auth/signin') { 113 | console.log(JSON.stringify(args)) 114 | } 115 | var formData = new FormData(); 116 | var keys = Object.keys(args) 117 | for(var index of keys) { 118 | formData.append(index, args[index]); 119 | } 120 | return that.req(endpoint, 'POST', formData, 'application/x-www-form-urlencoded; charset=utf-8') 121 | }) 122 | } 123 | 124 | auth() { 125 | console.log('auth/signin') 126 | var formData = new FormData(); 127 | formData.append('email', this.opts.username) 128 | formData.append('password', this.opts.password) 129 | return this.req('auth/signin', 'POST', formData, 'application/x-www-form-urlencoded; charset=utf-8') 130 | } 131 | 132 | whoami() { 133 | return this.get('auth/me') 134 | } 135 | 136 | seasons() { 137 | return this.get('leaderboard/seasons') 138 | } 139 | 140 | find(mode, season, user) { 141 | return this.get('leaderboard/find', { 142 | 'mode': mode, 143 | 'season': season, 144 | 'username': user 145 | }) 146 | } 147 | 148 | overview(interval, statName) { 149 | return this.get('user/overview', { 150 | 'interval': interval, 151 | 'statName': statName 152 | }) 153 | } 154 | 155 | my_orders() { 156 | return this.get('game/market/my-orders') 157 | } 158 | 159 | money_history(page=0) { 160 | return this.get('user/money-history', { 161 | 'page': page 162 | }) 163 | } 164 | 165 | user_console(cmd) { 166 | return this.post('user/console', {'expression':cmd}) 167 | } 168 | 169 | messages() { 170 | return this.get('user/messages/index') 171 | } 172 | 173 | messages_list(respondent) { 174 | return this.get('user/messages/list', {'respondent': respondent}) 175 | } 176 | 177 | messages_send(respondent, message) { 178 | return this.post('user/messages/send', {'respondent': respondent, 'text': message}) 179 | } 180 | 181 | userdata_from_id(id) { 182 | if(!this.id_user_map) { 183 | this.id_user_map = {} 184 | } 185 | if(!this.user_id_map) { 186 | this.user_id_map = {} 187 | } 188 | 189 | if(!!this.id_user_map[id]) { 190 | return Promise.resolve(this.id_user_map[id]) 191 | } 192 | var that = this 193 | return this.user_find({'id':id}) 194 | .then(function(data){ 195 | that.id_user_map[id] = data 196 | that.id_user_map[data['user']['username']] = data 197 | return data 198 | }) 199 | } 200 | 201 | userdata_from_username(username) { 202 | if(!this.user_id_map) { 203 | this.user_id_map = {} 204 | } 205 | if(!this.id_user_map) { 206 | this.id_user_map = {} 207 | } 208 | 209 | if(!!this.user_id_map[username]) { 210 | return Promise.resolve(this.user_id_map[username]) 211 | } 212 | var that = this 213 | return this.user_find({'username':username}) 214 | .then(function(data){ 215 | that.user_id_map[username] = data 216 | that.id_user_map[data['user']['_id']] = data 217 | return data 218 | }) 219 | } 220 | 221 | user_find(options) { 222 | return this.get('user/find', options) 223 | } 224 | 225 | } 226 | 227 | class ScreepsSocket { 228 | 229 | constructor(api, opts) { 230 | this.api = api 231 | this.opts = opts 232 | this.socket = false 233 | this.subscriptions = [] 234 | this.handlers = {} 235 | } 236 | 237 | connect() { 238 | 239 | if(!!this.socket) { 240 | // If socket is closed or closing then open a new one. 241 | if(this.socket.readyState == 2 || this.socket.readyState == 3) { 242 | this.socket = false 243 | } else { 244 | return 245 | } 246 | } 247 | 248 | var uri = !!this.opts.insecure ? 'ws://' : 'wss://' 249 | uri += this.opts.host + 'socket/websocket' 250 | console.log('connecting to websocket: ' + uri) 251 | this.socket = new WebSocket(uri) 252 | 253 | var that = this 254 | this.socket.addEventListener('open', function(evt){ 255 | evt.target.send('auth ' + that.api.token) 256 | }) 257 | 258 | 259 | this.socket.addEventListener('message', function(evt){ 260 | console.log('message received') 261 | 262 | var message = evt.data 263 | if(message.startsWith('auth ok')) { 264 | console.log('authenticated') 265 | var splitmessage = message.split(' ') 266 | if(splitmessage.length >= 3) { 267 | that.api.token = splitmessage[2] 268 | } 269 | // Set Subscriptions 270 | for(var watchpoint of that.subscriptions) { 271 | that.subscribe(watchpoint) 272 | } 273 | return 274 | } 275 | 276 | if(message.startsWith('time')) { 277 | return 278 | } 279 | 280 | if(message.startsWith('gz')) { 281 | message = inflate(message) 282 | } 283 | 284 | if (message[0] == '[') { 285 | var data = JSON.parse(message) 286 | } else { 287 | // emulate normal responses but with blank subscription key 288 | // this will mean only raw handlers will run on message 289 | var data = ['', message] 290 | } 291 | 292 | var handlers = [] 293 | switch (true) { 294 | case data[0].endsWith('console'): 295 | var type = 'console' 296 | break; 297 | case data[0].endsWith('cpu'): 298 | var type = 'cpu' 299 | break; 300 | case data[0].endsWith('money'): 301 | var type = 'money' 302 | break; 303 | default: 304 | var type = 'raw' 305 | break; 306 | } 307 | 308 | console.log('websocket handler type: ' + type) 309 | if(that.handlers[type]) { 310 | handlers = that.handlers[type] 311 | } 312 | 313 | if(that.handlers['*']) { 314 | handlers = handlers.concat(that.handlers[raw]) 315 | } 316 | 317 | for(var handler of handlers) { 318 | handler(data[1]) 319 | } 320 | }) 321 | 322 | 323 | this.socket.addEventListener('close', function(evt){ 324 | that.socket = false 325 | console.log("The Socket was Closed:", evt.code, evt.reason); 326 | }) 327 | 328 | 329 | this.socket.addEventListener('error', function(evt){ 330 | console.log("The socket had an error", evt.error) 331 | }) 332 | } 333 | 334 | disconnect() { 335 | if(this.socket) { 336 | console.log('closing socket') 337 | this.socket.close() 338 | this.socket = false 339 | } 340 | } 341 | 342 | subscribe(watchpoint) { 343 | if(this.subscriptions.indexOf(watchpoint) < 0) { 344 | this.subscriptions.push(watchpoint) 345 | this.connect() 346 | } 347 | 348 | if(this.socket && this.socket.readyState == 1) { 349 | var that = this 350 | this.api.userdata_from_username(this.opts.username) 351 | .then(function(userinfo){ 352 | var message = 'subscribe user:' + userinfo['user']['_id'] + '/' + watchpoint 353 | console.log(message) 354 | that.socket.send(message) 355 | }).catch(function(err){ 356 | console.log(err.message) 357 | console.log(err.stack) 358 | }) 359 | } 360 | } 361 | 362 | unsubscribe(watchpoint) { 363 | if(this.socket && this.socket.readyState == 1) { 364 | var that = this 365 | this.api.userdata_from_username(this.opts.username) 366 | .then(function(userinfo){ 367 | var message = 'unsubscribe user:' + userinfo['user']['_id'] + '/' + watchpoint 368 | console.log(message) 369 | that.socket.send(message) 370 | }) 371 | } 372 | var index = this.subscriptions.indexOf(watchpoint) 373 | if(index < 0) { 374 | this.subscriptions.splice(index,1) 375 | } 376 | if(this.subscriptions.length < 1) { 377 | this.disconnect() 378 | } 379 | } 380 | 381 | registerHandler(watchpoint, callback) { 382 | if(!this.handlers[watchpoint]) { 383 | this.handlers[watchpoint] = [] 384 | } 385 | this.handlers[watchpoint].push(callback) 386 | this.subscribe(watchpoint) 387 | } 388 | 389 | deregisterHandler(watchpoint, callback) { 390 | if(!this.handlers[watchpoint]) { 391 | return 392 | } 393 | 394 | var index = this.handlers[watchpoint].indexOf(callback) 395 | if(index >= 0) { 396 | console.log('removing handler from ' + watchpoint) 397 | this.handlers[watchpoint].splice(index, 1) 398 | } else { 399 | console.log('unable to find registered handler for ' + watchpoint) 400 | } 401 | 402 | if(this.handlers[watchpoint].length < 1) { 403 | console.log('unsubscribing from ' + watchpoint + ' due to lack of subscriptions') 404 | delete this.handlers[watchpoint] 405 | this.unsubscribe(watchpoint) 406 | } 407 | 408 | var handlercount = 0 409 | Object.values(this.handlers).forEach(function(e){handlercount += e.length; }) 410 | 411 | if(handlercount < 1) { 412 | console.log('closing socket due to lack of active subscriptions') 413 | this.disconnect() 414 | } 415 | } 416 | } 417 | 418 | 419 | 420 | var GCL_POW= 2.4 421 | var GCL_MULTIPLY = 1000000 422 | 423 | 424 | var POWER_POW = 1.15 425 | var POWER_MULTIPLY = 1000 426 | 427 | var powertotals = [{level:0, total:0}] 428 | var powerlevels = {} 429 | var total = 0 430 | for(var i=1; i <= 350; i++) { 431 | total += Math.pow(POWER_POW, i) * POWER_MULTIPLY 432 | powertotals.push({ 433 | level: i, 434 | total: total 435 | }) 436 | powerlevels[i] = total 437 | } 438 | powertotals.reverse() // store from highest to lowest 439 | 440 | 441 | var ScreepsUtils = { 442 | gclToControlPoints: function(gcl) { 443 | return Math.pow(gcl - 1, GCL_POW) * GCL_MULTIPLY; 444 | }, 445 | 446 | controlPointsToGcl: function(points) { 447 | return Math.floor(Math.pow(points / GCL_MULTIPLY, 1 / GCL_POW) + 1); 448 | }, 449 | 450 | powerToLevel: function (power) { 451 | if(power <= 0) { 452 | 453 | } 454 | for(var powerdata of powertotals) { 455 | if(powerdata.total < power) { 456 | return powerdata.level 457 | } 458 | } 459 | return false 460 | }, 461 | 462 | powerAtLevel: function (level) { 463 | return powerlevels[level] 464 | }, 465 | 466 | powerToNextLevel: function (level) { 467 | return Math.pow(POWER_POW, level) * POWER_MULTIPLY 468 | } 469 | } 470 | 471 | function gz (data) { 472 | let buf = new Buffer(data.slice(3), 'base64') 473 | let zlib = require('zlib') 474 | let ret = zlib.gunzipSync(buf).toString() 475 | return JSON.parse(ret) 476 | } 477 | 478 | function inflate (data) { 479 | let buf = new Buffer(data.slice(3), 'base64') 480 | let zlib = require('zlib') 481 | let ret = zlib.inflateSync(buf).toString() 482 | return JSON.parse(ret) 483 | } 484 | 485 | var api = new ScreepsAPI({}) 486 | api.utils = ScreepsUtils 487 | module.exports = api 488 | -------------------------------------------------------------------------------- /app/services/session.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('./screeps.js') 2 | var League = require('./league.js') 3 | var timer = require("timer"); 4 | 5 | class Session { 6 | 7 | construct() { 8 | this.timer = false 9 | } 10 | 11 | isLoaded() { 12 | return(!!this.userdata && !!this.userdata.username) 13 | } 14 | 15 | loadUser() { 16 | this.userdata = {} 17 | var that = this 18 | var session = that 19 | var current_season = false 20 | var that = this 21 | if(!this.timer) { 22 | this.timer = timer.setInterval(() => { 23 | that.loadUser() 24 | }, 1000 * 60 * 2) 25 | } 26 | 27 | 28 | // Return promise chain 29 | 30 | return ScreepsAPI.whoami() 31 | 32 | .then(function(data){ 33 | 34 | that.userdata.username = data.username 35 | that.userdata.cpu = data.cpu 36 | that.userdata.badge = data.badge 37 | that.userdata.controlpoints = Math.ceil(data.gcl) 38 | that.userdata.gcl = Math.ceil(ScreepsAPI.utils.controlPointsToGcl(data.gcl)) 39 | 40 | var gcl_current_start = ScreepsAPI.utils.gclToControlPoints(that.userdata.gcl) 41 | var gcl_next_start = ScreepsAPI.utils.gclToControlPoints(that.userdata.gcl+1) 42 | 43 | 44 | that.userdata.gcl_progressTotal = Math.ceil(gcl_next_start - gcl_current_start) 45 | that.userdata.gcl_progress = Math.ceil(that.userdata.controlpoints - gcl_current_start) 46 | that.userdata.gcl_progress_percentage = Math.round((that.userdata.gcl_progress / that.userdata.gcl_progressTotal) * 100) 47 | that.userdata.gcl_progressTotal_string = that.userdata.gcl_progressTotal.toAbbreviated() 48 | that.userdata.gcl_progress_string = that.userdata.gcl_progress.toAbbreviated() 49 | 50 | that.userdata.power = data.power 51 | that.userdata.power_level = ScreepsAPI.utils.powerToLevel(data.power) 52 | var power_current_start = ScreepsAPI.utils.powerAtLevel(that.userdata.power_level) 53 | var power_next_start = ScreepsAPI.utils.powerAtLevel(that.userdata.power_level+1) 54 | 55 | that.userdata.power_progressTotal = Math.ceil(power_next_start - power_current_start) 56 | that.userdata.power_progress = Math.ceil(that.userdata.power - power_current_start) 57 | that.userdata.power_progress_percentage = Math.round((that.userdata.power_progress / that.userdata.power_progressTotal) * 100) 58 | that.userdata.power_progressTotal_string = that.userdata.power_progressTotal.toAbbreviated() 59 | that.userdata.power_progress_string = that.userdata.power_progress.toAbbreviated() 60 | 61 | 62 | 63 | that.userdata.money = (Math.round(100*data.money)/100).toFixed(2) 64 | that.userdata.alliance = League.getUserAlliance(data.username) 65 | 66 | var alliance = League.getAlliance(League.getUserAlliance(data.username)) 67 | if(alliance) { 68 | that.userdata.alliance = alliance.abbreviation 69 | that.userdata.alliance_name = alliance.name 70 | } 71 | 72 | that.userdata.badge_url = League.getBadgeUrl(data.username) 73 | return ScreepsAPI.seasons() 74 | }) 75 | 76 | // Set Current Season 77 | .then(function(data){ 78 | var seasons = data['seasons'] 79 | seasons.sort(function(a,b){ 80 | a = new Date(a.dateModified); 81 | b = new Date(b.dateModified); 82 | return a>b ? -1 : a 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/shared/widgets/navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/views/about/about.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/about/about.css -------------------------------------------------------------------------------- /app/views/about/about.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frame = require("ui/frame");1 4 | var utils = require("utils/utils"); 5 | 6 | exports.onTap = require("../../shared/navtools.js").onTap 7 | 8 | var page; 9 | var drawer; 10 | 11 | exports.pageLoaded = function(args) { 12 | page = args.object; 13 | var source = {} 14 | drawer = page.getViewById("drawer"); 15 | page.getViewById("title").text = 'About' 16 | // Additional on load actions here 17 | }; 18 | 19 | exports.toggleDrawer = function() { 20 | drawer.toggleDrawerState(); 21 | }; 22 | 23 | exports.goToGithub = function () { 24 | utils.openUrl('https://github.com/tedivm/Spawn1') 25 | } 26 | 27 | exports.goToScreeps = function () { 28 | utils.openUrl('https://screeps.com/') 29 | } 30 | -------------------------------------------------------------------------------- /app/views/about/about.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/views/alliance/alliance.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/alliance/alliance.css -------------------------------------------------------------------------------- /app/views/alliance/alliance.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frame = require("ui/frame"); 4 | var utils = require("utils/utils"); 5 | var timer = require("timer"); 6 | exports.onTap = require("../../shared/navtools.js").onTap 7 | 8 | var page; 9 | var drawer; 10 | var timerid = false 11 | 12 | exports.pageLoaded = function(args) { 13 | page = args.object; 14 | var source = {} 15 | drawer = page.getViewById("drawer"); 16 | //page.getViewById("title").text = '' 17 | // Additional on load actions here 18 | 19 | if(!!page.bindingContext.delayedReload) { 20 | timerid = timer.setTimeout(() => { 21 | delete page.bindingContext.delayedReload 22 | //frame.reloadPage() 23 | 24 | frame.topmost().navigate({ 25 | moduleName: "views/alliance/alliance", 26 | bindingContext: page.bindingContext, 27 | backstackVisible: false, 28 | animated: false 29 | }); 30 | 31 | }, 1000 * 3); 32 | } 33 | 34 | }; 35 | 36 | exports.pageUnloaded = function(args) { 37 | if(!!timerid) { 38 | timer.clearInterval(timerid) 39 | timerid = false 40 | } 41 | } 42 | 43 | exports.toggleDrawer = function() { 44 | drawer.toggleDrawerState(); 45 | }; 46 | 47 | 48 | exports.loadSlack = function(args) { 49 | utils.openUrl(page.bindingContext['slackurl']) 50 | } 51 | 52 | exports.loadMemberPage = function(args) { 53 | //page.bindingContext['memberObjects'] 54 | frame.topmost().navigate({ 55 | moduleName: "views/alliance/members", 56 | bindingContext: page.bindingContext 57 | }); 58 | } 59 | -------------------------------------------------------------------------------- /app/views/alliance/alliance.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/views/alliance/members.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frames = require("ui/frame"); 4 | var utils = require("utils/utils"); 5 | exports.onTap = require("../../shared/navtools.js").onTap 6 | 7 | var page; 8 | var drawer; 9 | 10 | exports.pageLoaded = function(args) { 11 | page = args.object; 12 | var source = {} 13 | drawer = page.getViewById("drawer"); 14 | //page.getViewById("title").text = '' 15 | // Additional on load actions here 16 | }; 17 | 18 | exports.toggleDrawer = function() { 19 | drawer.toggleDrawerState(); 20 | }; 21 | -------------------------------------------------------------------------------- /app/views/alliance/members.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/views/alliances/alliances.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/alliances/alliances.css -------------------------------------------------------------------------------- /app/views/alliances/alliances.js: -------------------------------------------------------------------------------- 1 | var League = require('../../services/league.js') 2 | var ScreepsAPI = require('../../services/screeps.js') 3 | var Session = require('../../services/session.js') 4 | var frame = require("ui/frame"); 5 | 6 | exports.onTap = require("../../shared/navtools.js").onTap 7 | 8 | 9 | var Observable = require("data/observable").Observable; 10 | var ObservableArray = require("data/observable-array").ObservableArray; 11 | var utils = require("utils/utils"); 12 | 13 | var items = new ObservableArray([]); 14 | var pageData = new Observable(); 15 | 16 | 17 | var page; 18 | var drawer; 19 | 20 | // http://www.leagueofautomatednations.com/obj/7d0f0ab264d4a26.jpg 21 | 22 | 23 | function loadAlliances () { 24 | var alliances = League.getAllianceData() 25 | alliances.sort(function(a,b){ 26 | var textA = a.abbreviation.toUpperCase(); 27 | var textB = b.abbreviation.toUpperCase(); 28 | return (textA < textB) ? -1 : (textA > textB) ? 1 : 0; 29 | }) 30 | 31 | // Remove existing itms and repopulate. 32 | items.length = 0 33 | for(var alliance of alliances) { 34 | items.push(alliance) 35 | } 36 | } 37 | 38 | 39 | 40 | 41 | exports.pageLoaded = function(args) { 42 | page = args.object; 43 | var source = {} 44 | drawer = page.getViewById("drawer"); 45 | page.getViewById("title").text = 'Alliances' 46 | // Additional on load actions here 47 | page.bindingContext = pageData; 48 | loadAlliances() 49 | pageData.set("items", items); 50 | }; 51 | 52 | exports.toggleDrawer = function() { 53 | drawer.toggleDrawerState(); 54 | }; 55 | 56 | exports.listViewItemTap = function(args) { 57 | var item = items.getItem(args.index); 58 | frame.topmost().navigate({ 59 | moduleName: "views/alliance/alliance", 60 | bindingContext: League.getAlliance(item.abbreviation) 61 | }); 62 | } 63 | -------------------------------------------------------------------------------- /app/views/alliances/alliances.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/views/category_template/template.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/category_template/template.css -------------------------------------------------------------------------------- /app/views/category_template/template.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frame = require("ui/frame"); 4 | exports.onTap = require("../../shared/navtools.js").onTap 5 | 6 | var page; 7 | var drawer; 8 | 9 | exports.pageLoaded = function(args) { 10 | page = args.object; 11 | var source = {} 12 | drawer = page.getViewById("drawer"); 13 | page.getViewById("title").text = 'TITLE' 14 | // Additional on load actions here 15 | }; 16 | 17 | exports.toggleDrawer = function() { 18 | drawer.toggleDrawerState(); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /app/views/category_template/template.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/views/console/console.css: -------------------------------------------------------------------------------- 1 | Page { 2 | background-color: #243044; 3 | } 4 | .console_background { 5 | background-color: #243044; 6 | color: white 7 | } 8 | .console_output { 9 | background-color: #243044; 10 | font-size: 12; 11 | } 12 | .console_list { 13 | separator-color: #243044; 14 | } -------------------------------------------------------------------------------- /app/views/console/console.js: -------------------------------------------------------------------------------- 1 | var League = require('../../services/league.js') 2 | var ScreepsAPI = require('../../services/screeps.js') 3 | var Session = require('../../services/session.js') 4 | var frame = require("ui/frame"); 5 | var timer = require("timer"); 6 | 7 | exports.onTap = require("../../shared/navtools.js").onTap 8 | 9 | 10 | var Observable = require("data/observable").Observable; 11 | var ObservableArray = require("data/observable-array").ObservableArray; 12 | var utils = require("utils/utils"); 13 | 14 | var items = new ObservableArray([]); 15 | var pageData = new Observable(); 16 | 17 | 18 | var page; 19 | var drawer; 20 | var socket = false 21 | var maxbuffer = 1000 22 | 23 | var display_errors = true 24 | var display_log = true 25 | var display_results = true 26 | var display = { 27 | 'error': true, 28 | 'result': true, 29 | 'log': true 30 | } 31 | 32 | 33 | function addItem(type, message) { 34 | 35 | if(!display[type]) { 36 | return 37 | } 38 | 39 | if(message.startsWith('ScreepStats')) { 40 | return 41 | } 42 | 43 | var color = type == 'error' ? 'DD0000' : '#FFFFFF' 44 | 45 | if(items.length >= maxbuffer) { 46 | items.shift() 47 | } 48 | 49 | items.push({ 50 | 'type': type, 51 | 'message': '' + message + '' 52 | }) 53 | 54 | } 55 | 56 | function console_message(socket_data) { 57 | var should_refocus = false 58 | 59 | // Uncaught errors *in game* 60 | if(socket_data['error']) { 61 | should_refocus = true 62 | addItem('error', socket_data['error']) 63 | } 64 | 65 | if(socket_data['messages']) { 66 | // Standard output from console.log 67 | if(socket_data['messages']['log'] && socket_data['messages']['log'].length > 0) { 68 | should_refocus = true 69 | for(var log of socket_data['messages']['log']) { 70 | addItem('log', log) 71 | } 72 | } 73 | 74 | // Return output from console commands 75 | if(socket_data['messages']['results'] && socket_data['messages']['results'].length > 0) { 76 | should_refocus = true 77 | for(var result of socket_data['messages']['results']) { 78 | addItem('result', result) 79 | } 80 | } 81 | } 82 | 83 | if(should_refocus) { 84 | refocus() 85 | } 86 | } 87 | 88 | 89 | function refocus() { 90 | var console_buffer = page.getViewById("console_list"); 91 | if(items.length > 0) { 92 | console_buffer.scrollToIndex(console_buffer.items.length - 1); // scroll to the bottom 93 | } 94 | } 95 | 96 | 97 | exports.pageLoaded = function(args) { 98 | page = args.object; 99 | var source = {} 100 | drawer = page.getViewById("drawer"); 101 | page.getViewById("title").text = 'console' 102 | // Additional on load actions here 103 | 104 | items.length = 0 105 | 106 | page.bindingContext = pageData; 107 | 108 | // create websocket connection to server 109 | console.log('loading socket') 110 | socket = ScreepsAPI.get_web_socket() 111 | socket.registerHandler('console', console_message) 112 | pageData.set("messages", items); 113 | 114 | }; 115 | 116 | exports.pageUnloaded = function (args) { 117 | console.log('unloading console') 118 | if(!!socket) { 119 | socket.deregisterHandler('console', console_message) 120 | } 121 | } 122 | 123 | 124 | exports.toggleDrawer = function() { 125 | drawer.toggleDrawerState(); 126 | } 127 | 128 | exports.sendConsoleCommand = function (args) { 129 | var message_input = page.getViewById("message_input") 130 | var message = message_input.text 131 | ScreepsAPI.user_console(message) 132 | message_input.text = '' 133 | } 134 | -------------------------------------------------------------------------------- /app/views/console/console.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/views/login/login.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/login/login.css -------------------------------------------------------------------------------- /app/views/login/login.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frames = require("ui/frame"); 4 | var page; 5 | 6 | var isAttempting = false 7 | 8 | exports.loaded = function(args) { 9 | page = args.object; 10 | var testing = {} 11 | page.bindingContext = testing 12 | page.bindingContext['activity'] = false 13 | isAttempting = false 14 | //testing["activity"] = false 15 | //page.bindingContext.set("activity",false) 16 | }; 17 | 18 | exports.signIn = function() { 19 | 20 | if(isAttempting) { 21 | return 22 | } 23 | isAttempting = true 24 | 25 | var username_view = page.getViewById("username"); 26 | var password_view = page.getViewById("password"); 27 | 28 | 29 | var username = username_view.text; 30 | var password = password_view.text; 31 | 32 | if(!!ScreepsAPI.token) { 33 | if(ScreepsAPI.username == username) { 34 | if(ScreepsAPI.password == password) { 35 | // already logged in as this user- probably hit the button too fast. 36 | return 37 | } 38 | } 39 | } 40 | 41 | 42 | ScreepsAPI.username = username 43 | ScreepsAPI.password = password 44 | page.bindingContext['activity'] = true 45 | 46 | ScreepsAPI.auth() 47 | .then(function(data){ 48 | if(data['token']) { 49 | Session.loadUser().then(function(){ 50 | var indicator = frames.topmost().currentPage.getViewById('ActivityIndicator') 51 | //indicator.busy = false 52 | page.bindingContext["activity"] = false 53 | frames.topmost().navigate({ 54 | 'moduleName': "views/profile/profile", 55 | 'clearHistory': true 56 | }); 57 | }) 58 | } else { 59 | alert('sign in failed') 60 | password_view.text = '' 61 | } 62 | isAttempting = false 63 | }) 64 | .catch(function (response){ 65 | isAttempting = false 66 | console.log(response.message) 67 | page.bindingContext['activity'] = true 68 | alert('sign in failed') 69 | }) 70 | 71 | }; 72 | -------------------------------------------------------------------------------- /app/views/login/login.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/views/messages/messages.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/messages/messages.css -------------------------------------------------------------------------------- /app/views/messages/messages.js: -------------------------------------------------------------------------------- 1 | var League = require('../../services/league.js') 2 | var ScreepsAPI = require('../../services/screeps.js') 3 | var Session = require('../../services/session.js') 4 | var dialogs = require("ui/dialogs"); 5 | var frame = require("ui/frame"); 6 | var timer = require("timer"); 7 | 8 | exports.onTap = require("../../shared/navtools.js").onTap 9 | 10 | 11 | var Observable = require("data/observable").Observable; 12 | var ObservableArray = require("data/observable-array").ObservableArray; 13 | var utils = require("utils/utils"); 14 | 15 | var items = new ObservableArray([]); 16 | var pageData = new Observable(); 17 | 18 | 19 | var page; 20 | var drawer; 21 | var conversationTimerID = false 22 | 23 | var refreshTime = 2 // minutes 24 | 25 | function loadMessages () { 26 | return ScreepsAPI.messages() 27 | .then(function(data){ 28 | 29 | var promiseCollection = [] 30 | var username_mapping = {} 31 | for(var conversation of data['messages']) { 32 | promiseCollection.push( 33 | ScreepsAPI.userdata_from_id(conversation.message.respondent) 34 | .then(function(data){ 35 | username_mapping[data['user']['_id']] = data['user']['username'] 36 | return Promise.resolve(true) 37 | }) 38 | ) 39 | } 40 | 41 | return Promise.all(promiseCollection) 42 | .then(function(){ 43 | for(var conversation of data['messages']) { 44 | conversation['message']['rusername'] = username_mapping[conversation['message']['respondent']] 45 | var date = new Date(conversation['message']['date']); 46 | conversation['message']['date_locale'] = date.toLocaleString() 47 | conversation['message']['badge_url'] = League.getBadgeUrl(conversation['message']['rusername']) 48 | } 49 | return data 50 | }) 51 | }) 52 | 53 | .then(function(data){ 54 | // Remove existing itms and repopulate. 55 | items.length = 0 56 | for(var conversation of data['messages']) { 57 | items.push(conversation['message']) 58 | } 59 | 60 | return Promise.resolve(true) 61 | }) 62 | .catch(function(err) { 63 | console.log(err.message) 64 | console.log(err.stack) 65 | }) 66 | } 67 | 68 | 69 | exports.pageLoaded = function(args) { 70 | page = args.object; 71 | var source = {} 72 | drawer = page.getViewById("drawer"); 73 | page.getViewById("title").text = 'Messages' 74 | 75 | // Additional on load actions here 76 | page.bindingContext = pageData; 77 | loadMessages() 78 | pageData.set("conversations", items); 79 | conversationTimerID = timer.setInterval(function(){ 80 | loadMessages() 81 | }, (1000 * 60 * refreshTime)) 82 | }; 83 | 84 | exports.composeMessage = function (args) { 85 | 86 | dialogs.prompt({ 87 | title: "Compose Message", 88 | message: "Select User", 89 | okButtonText: "Ok", 90 | cancelButtonText: "Cancel", 91 | neutralButtonText: false, 92 | defaultText: "", 93 | inputType: dialogs.inputType.text 94 | }) 95 | .then(function (r) { 96 | return r.text 97 | }) 98 | .then(function(username){ 99 | return ScreepsAPI.userdata_from_username(username) 100 | }) 101 | .then(function(data){ 102 | var pageData = new Observable(); 103 | pageData.recipient = data['user']['username'] 104 | pageData.respondent = data['user']['_id'] 105 | pageData.messages = [] 106 | frame.topmost().navigate({ 107 | moduleName: "views/messages/conversation", 108 | bindingContext: pageData 109 | }) 110 | }) 111 | .catch(function(err){ 112 | console.log(err.message) 113 | console.log(err.stack) 114 | }) 115 | } 116 | 117 | exports.toggleDrawer = function() { 118 | drawer.toggleDrawerState(); 119 | }; 120 | 121 | exports.listViewItemTap = function (args) { 122 | var item = items.getItem(args.index); 123 | var pageData = new Observable(); 124 | pageData.recipient = item.rusername 125 | pageData.respondent = item.respondent 126 | pageData.messages = [] 127 | frame.topmost().navigate({ 128 | moduleName: "views/messages/conversation", 129 | bindingContext: pageData 130 | }) 131 | } 132 | 133 | exports.pageUnloaded = function (args) { 134 | if(conversationTimerID !== false) { 135 | timer.clearInterval(conversationTimerID) 136 | conversationTimerID = false 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/views/messages/messages.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/views/orders/orders.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/orders/orders.css -------------------------------------------------------------------------------- /app/views/orders/orders.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frames = require("ui/frame"); 4 | var dialogs = require("ui/dialogs"); 5 | exports.onTap = require("../../shared/navtools.js").onTap 6 | 7 | var page; 8 | var drawer; 9 | 10 | 11 | var Observable = require("data/observable").Observable; 12 | var ObservableArray = require("data/observable-array").ObservableArray; 13 | var utilsModule = require("utils/utils"); 14 | 15 | var items = new ObservableArray([]); 16 | var pageData = new Observable(); 17 | 18 | function loadOrders () { 19 | // Toss a few numbers in the list for testing 20 | return ScreepsAPI.my_orders() 21 | .then(function(data){ 22 | console.log('market orders loaded') 23 | items.length = 0 24 | for(var order of data['list']) { 25 | // Subscription tokens will need to be excluded until the layout 26 | // templates are updated. 27 | if(!order['roomName']) { 28 | continue 29 | } 30 | 31 | items.push(order) 32 | } 33 | return Promise.resolve(true) 34 | }) 35 | } 36 | 37 | exports.pageLoaded = function(args) { 38 | page = args.object; 39 | var source = {} 40 | drawer = page.getViewById("drawer"); 41 | page.getViewById("title").text = 'Orders' 42 | 43 | page.bindingContext = pageData; 44 | loadOrders() 45 | pageData.set("items", items); 46 | }; 47 | 48 | exports.toggleDrawer = function() { 49 | drawer.toggleDrawerState(); 50 | }; 51 | 52 | exports.pullToRefreshInitiated = function() { 53 | // Load orders and then reset the UI 54 | loadOrders() 55 | .then(function(){ 56 | page.getViewById("list-view").notifyPullToRefreshFinished(); 57 | }) 58 | }; 59 | 60 | function getSwipeThreshold() { 61 | return 100 * utilsModule.layout.getDisplayDensity(); 62 | } 63 | 64 | exports.itemSwipeProgressStarted = function(args) { 65 | var swipeLimits = args.data.swipeLimits; 66 | var threshold = getSwipeThreshold() 67 | swipeLimits.threshold = threshold 68 | swipeLimits.left = threshold 69 | swipeLimits.right = threshold 70 | } 71 | 72 | // Clear order 73 | exports.itemSwipeProgressEnded = function(args) { 74 | var item = items.getItem(args.itemIndex); 75 | 76 | var swipeThreshold = getSwipeThreshold() 77 | if (args.data.x <= -(swipeThreshold) || args.data.x >= swipeThreshold) { 78 | // @todo ask for confirmation and then delete it 79 | dialogs.confirm("Are you sure you want to cancel this order?") 80 | .then(function (result) { 81 | if(result) { 82 | // Delete Order 83 | items.splice(args.itemIndex, 1); 84 | ScreepsAPI.user_console('Game.market.cancelOrder("' + item['_id'] + '")') 85 | } 86 | return result 87 | }) 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /app/views/orders/orders.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /app/views/profile/profile.css: -------------------------------------------------------------------------------- 1 | .user_header { 2 | margin: 15; 3 | } -------------------------------------------------------------------------------- /app/views/profile/profile.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var League = require('../../services/league.js') 4 | var frame = require("ui/frame"); 5 | 6 | exports.onTap = require("../../shared/navtools.js").onTap 7 | 8 | var page; 9 | var drawer; 10 | 11 | exports.pageLoaded = function(args) { 12 | page = args.object; 13 | var source = {} 14 | 15 | drawer = page.getViewById("drawer"); 16 | page.getViewById("title").text = Session.userdata.username 17 | 18 | Session.loadUser() 19 | .then(function(){ 20 | page.bindingContext = Session.userdata 21 | }) 22 | }; 23 | 24 | exports.toggleDrawer = function() { 25 | drawer.toggleDrawerState(); 26 | }; 27 | 28 | 29 | exports.loadAlliancePage = function () { 30 | var new_context = League.getAlliance(Session.userdata.alliance) 31 | new_context.delayedReload = true 32 | frame.topmost().navigate({ 33 | moduleName: "views/alliance/alliance", 34 | bindingContext: new_context 35 | }) 36 | } 37 | 38 | exports.loadWalletPage = function () { 39 | frame.topmost().navigate({ 40 | 'moduleName': "views/wallet/wallet", 41 | 'clearHistory': true 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /app/views/profile/profile.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/views/server/server.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/server/server.css -------------------------------------------------------------------------------- /app/views/server/server.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frames = require("ui/frame"); 4 | exports.onTap = require("../../shared/navtools.js").onTap 5 | 6 | var page; 7 | var drawer; 8 | 9 | exports.pageLoaded = function(args) { 10 | page = args.object; 11 | var source = {} 12 | drawer = page.getViewById("drawer"); 13 | page.getViewById("title").text = 'Server Speed' 14 | // Additional on load actions here 15 | }; 16 | 17 | exports.toggleDrawer = function() { 18 | drawer.toggleDrawerState(); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /app/views/server/server.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/views/wallet/transaction.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/wallet/transaction.css -------------------------------------------------------------------------------- /app/views/wallet/transaction.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frame = require("ui/frame"); 4 | 5 | var page; 6 | 7 | exports.pageLoaded = function(args) { 8 | page = args.object; 9 | var source = {} 10 | drawer = page.getViewById("drawer"); 11 | page.getViewById("title").text = 'Transaction' 12 | // Additional on load actions here 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /app/views/wallet/transaction.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/views/wallet/wallet.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedivm/Spawn1/ffb704d1c10a606b9276e8033c5b6f5bca1022f3/app/views/wallet/wallet.css -------------------------------------------------------------------------------- /app/views/wallet/wallet.js: -------------------------------------------------------------------------------- 1 | var ScreepsAPI = require('../../services/screeps.js') 2 | var Session = require('../../services/session.js') 3 | var frame = require("ui/frame"); 4 | exports.onTap = require("../../shared/navtools.js").onTap 5 | 6 | var page; 7 | var drawer; 8 | 9 | var currentWalletPage = false 10 | 11 | var Observable = require("data/observable").Observable; 12 | var ObservableArray = require("data/observable-array").ObservableArray; 13 | var utilsModule = require("utils/utils"); 14 | 15 | var items = new ObservableArray([]); 16 | var pageData = new Observable(); 17 | 18 | function loadWalletHistory () { 19 | // Toss a few money_history in the list for testing 20 | return ScreepsAPI.money_history() 21 | .then(function(data){ 22 | console.log('wallet history loaded') 23 | currentWalletPage = 0 24 | items.length = 0 25 | 26 | for(var order of data['list']) { 27 | if(order['balance']) { 28 | order['balance'] = order['balance'].toFixed(2) 29 | order['direction'] = order['change'] > 0 ? 'credit' : 'debit' 30 | } 31 | items.push(order) 32 | } 33 | return Promise.resolve(true) 34 | }) 35 | } 36 | 37 | exports.pageLoaded = function(args) { 38 | page = args.object; 39 | var source = {} 40 | drawer = page.getViewById("drawer"); 41 | page.getViewById("title").text = 'Wallet' 42 | 43 | page.bindingContext = pageData; 44 | loadWalletHistory() 45 | pageData.set("items", items); 46 | }; 47 | 48 | exports.toggleDrawer = function() { 49 | drawer.toggleDrawerState(); 50 | }; 51 | 52 | exports.pullToRefreshInitiated = function() { 53 | // Simulate a call to a backend that comes back two seconds later 54 | loadWalletHistory() 55 | .then(function(){ 56 | page.getViewById("list-view").notifyPullToRefreshFinished(); 57 | }) 58 | }; 59 | 60 | exports.onLoadMoreItemsRequested = function() { 61 | currentWalletPage++ 62 | return ScreepsAPI.money_history(currentWalletPage) 63 | .then(function(data){ 64 | console.log('wallet history loaded') 65 | for(var order of data['list']) { 66 | if(order['balance']) { 67 | order['balance'] = order['balance'].toFixed(2) 68 | order['direction'] = order['change'] > 0 ? 'credit' : 'debit' 69 | } 70 | items.push(order) 71 | } 72 | return Promise.resolve(true) 73 | }) 74 | } 75 | 76 | exports.viewTransaction = function (args) { 77 | 78 | var item = items.getItem(args.itemIndex); 79 | console.dump(item) 80 | frame.topmost().navigate({ 81 | moduleName: "views/wallet/transaction", 82 | bindingContext: item 83 | }) 84 | } 85 | -------------------------------------------------------------------------------- /app/views/wallet/wallet.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/www/lib/es6-promise.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * @overview es6-promise - a tiny implementation of Promises/A+. 3 | * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 4 | * @license Licensed under MIT license 5 | * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE 6 | * @version 3.0.2 7 | */ 8 | 9 | (function(){"use strict";function lib$es6$promise$utils$$objectOrFunction(x){return typeof x==="function"||typeof x==="object"&&x!==null}function lib$es6$promise$utils$$isFunction(x){return typeof x==="function"}function lib$es6$promise$utils$$isMaybeThenable(x){return typeof x==="object"&&x!==null}var lib$es6$promise$utils$$_isArray;if(!Array.isArray){lib$es6$promise$utils$$_isArray=function(x){return Object.prototype.toString.call(x)==="[object Array]"}}else{lib$es6$promise$utils$$_isArray=Array.isArray}var lib$es6$promise$utils$$isArray=lib$es6$promise$utils$$_isArray;var lib$es6$promise$asap$$len=0;var lib$es6$promise$asap$$toString={}.toString;var lib$es6$promise$asap$$vertxNext;var lib$es6$promise$asap$$customSchedulerFn;var lib$es6$promise$asap$$asap=function asap(callback,arg){lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len]=callback;lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len+1]=arg;lib$es6$promise$asap$$len+=2;if(lib$es6$promise$asap$$len===2){if(lib$es6$promise$asap$$customSchedulerFn){lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush)}else{lib$es6$promise$asap$$scheduleFlush()}}};function lib$es6$promise$asap$$setScheduler(scheduleFn){lib$es6$promise$asap$$customSchedulerFn=scheduleFn}function lib$es6$promise$asap$$setAsap(asapFn){lib$es6$promise$asap$$asap=asapFn}var lib$es6$promise$asap$$browserWindow=typeof window!=="undefined"?window:undefined;var lib$es6$promise$asap$$browserGlobal=lib$es6$promise$asap$$browserWindow||{};var lib$es6$promise$asap$$BrowserMutationObserver=lib$es6$promise$asap$$browserGlobal.MutationObserver||lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;var lib$es6$promise$asap$$isNode=typeof process!=="undefined"&&{}.toString.call(process)==="[object process]";var lib$es6$promise$asap$$isWorker=typeof Uint8ClampedArray!=="undefined"&&typeof importScripts!=="undefined"&&typeof MessageChannel!=="undefined";function lib$es6$promise$asap$$useNextTick(){return function(){process.nextTick(lib$es6$promise$asap$$flush)}}function lib$es6$promise$asap$$useVertxTimer(){return function(){lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush)}}function lib$es6$promise$asap$$useMutationObserver(){var iterations=0;var observer=new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);var node=document.createTextNode("");observer.observe(node,{characterData:true});return function(){node.data=iterations=++iterations%2}}function lib$es6$promise$asap$$useMessageChannel(){var channel=new MessageChannel;channel.port1.onmessage=lib$es6$promise$asap$$flush;return function(){channel.port2.postMessage(0)}}function lib$es6$promise$asap$$useSetTimeout(){return function(){setTimeout(lib$es6$promise$asap$$flush,1)}}var lib$es6$promise$asap$$queue=new Array(1e3);function lib$es6$promise$asap$$flush(){for(var i=0;i} Returns a promise with value returned by canvas request handler. 67 | */ 68 | NSCanvasInterface._setImage = function (canvasId, functionName, base64IamgeStr, args) { 69 | var image = new Image(); 70 | return new Promise(function (resolve, reject) { 71 | image.onload = function () { 72 | try { 73 | var retnPromise = NSCanvasInterface._callCanvasReqHandler(canvasId, functionName, [image].concat(args)); 74 | if (!retnPromise) { 75 | throw 'Some Error Occurred while executing _callCanvasReqHandler'; 76 | } 77 | retnPromise.then(function (retnValue) { 78 | resolve(retnValue); 79 | }); 80 | } 81 | catch (e) { 82 | reject(e); 83 | } 84 | }; 85 | image.src = base64IamgeStr; 86 | }); 87 | }; 88 | /** 89 | * This function is called from plugin's native side code. 90 | * Executes the specified function with the passed arguments and generates 91 | * base64 encoded image from the canvas context. 92 | * 93 | * @private 94 | * @param {string} canvasId - Value of "id" attribute of the canvas element in web-view. 95 | * @param {string} functionName - Registered name of handler, which preforms canvas manipulation and creates image. 96 | * @param {string} imgFormat - Expected output format of the image. 97 | * @param {any[]} args - Array of arguments to pass while calling canvas request handler. 98 | * @returns {Promise<<{_strImage: string, data: any}>} Returns promise with base64 encoded image string and any data returned from the canvas request handler.. 99 | */ 100 | NSCanvasInterface._createImage = function (canvasId, functionName, imgFormat, args) { 101 | return new Promise(function (resolve, reject) { 102 | try { 103 | var retnPromise = NSCanvasInterface._callCanvasReqHandler(canvasId, functionName, args); 104 | if (!retnPromise) { 105 | throw 'Some Error Occurred while executing _callCanvasReqHandler'; 106 | } 107 | retnPromise.then(function (data) { 108 | var oNSCanvasInterface = NSCanvasInterface._getCanvasInstanceById(canvasId); 109 | var strImage = oNSCanvasInterface.canvas.toDataURL(imgFormat === 'png' ? 'image/png' : 'image/jpeg'); 110 | resolve({ 111 | _strImage: strImage, 112 | data: data 113 | }); 114 | }); 115 | } 116 | catch (e) { 117 | reject(e); 118 | } 119 | }); 120 | }; 121 | /** 122 | * A map of canvasId and its NSCanvasInterface instance. 123 | * 124 | * @private 125 | */ 126 | NSCanvasInterface._canvasInterfaceInstanceMap = {}; 127 | return NSCanvasInterface; 128 | })(); 129 | /** 130 | * Registering NSCanvasInterface class to global window variable, 131 | * to make it accessible to native app and web-view code. 132 | */ 133 | window.NSCanvasInterface = NSCanvasInterface; 134 | -------------------------------------------------------------------------------- /app/www/lib/nativescript-webview-interface.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WebViewInterface class to handle communication between webView and Android/iOS. 3 | */ 4 | var NSWebViewinterface = (function () { 5 | function NSWebViewinterface() { 6 | 7 | /** 8 | * Mapping of native eventName and its handler in webView 9 | */ 10 | this.eventListenerMap = {}; 11 | 12 | /** 13 | * Mapping of JS Call responseId and result for iOS 14 | */ 15 | this._iosResponseMap = {}; 16 | 17 | /** 18 | * Counter of iOS JS Call responseId 19 | */ 20 | this._iosCntResponseId = 0; 21 | } 22 | 23 | /** 24 | * Handles events/commands emitted by android/ios. This function is called from nativescript. 25 | * @param {string} eventName - Native event/command name 26 | * @param {data} data - Payload for the event/command 27 | */ 28 | NSWebViewinterface.prototype._onNativeEvent = function (eventName, data) { 29 | var lstEvtListeners = this.eventListenerMap[eventName] || []; 30 | for (var _i = 0; _i < lstEvtListeners.length; _i++) { 31 | var listener = lstEvtListeners[_i]; 32 | var retnVal = listener && listener(data); 33 | // if any handler return false, not executing any further handlers for that event. 34 | if (retnVal === false) { 35 | break; 36 | } 37 | } 38 | }; 39 | 40 | /** 41 | * Handles JS function calls by android/ios. This function is called from nativescript. 42 | * Result value of JS function call can be promise or any other data. 43 | * @param {number} reqId - Internal communication id 44 | * @param {string} functionName - Function to be executed in webView 45 | * @param {any[]} args 46 | */ 47 | NSWebViewinterface.prototype._callJSFunction = function (reqId, functionName, args) { 48 | var _this = this; 49 | var resolvedFn = _this._getResolvedFunction(functionName); 50 | if(resolvedFn){ 51 | var retnVal = resolvedFn.apply(window, args); 52 | if (retnVal && retnVal.then) { 53 | retnVal.then(function (value) { 54 | _this._sendJSCallResponse(reqId, value); 55 | }, function(error){ 56 | _this._sendJSCallResponse(reqId, error, true); 57 | }); 58 | } 59 | else { 60 | this._sendJSCallResponse(reqId, retnVal); 61 | } 62 | } 63 | } 64 | 65 | /** 66 | * Resolves a function, if the function to be executed is in deep object chain. 67 | * e.g If we want to execute a function 'parent.child.child.fn' from native app, 68 | * this function will extract fn from the object chain. 69 | * We can do it by using eval also, but as there is a way, why to invite unknown security risks? 70 | * 71 | */ 72 | NSWebViewinterface.prototype._getResolvedFunction = function(functionName){ 73 | if(functionName && (functionName = functionName.trim()).length){ 74 | functionName = functionName.indexOf('window.') === 0 ? functionName.replace('window.', '') : functionName; 75 | var arrFnPath = functionName.split('.'); 76 | var fn = window; 77 | for(var i =0; i < arrFnPath.length; i++){ 78 | if(!fn[arrFnPath[i]]){ 79 | fn = null; 80 | break; 81 | } 82 | fn = fn[arrFnPath[i]]; 83 | } 84 | return fn; 85 | } 86 | } 87 | 88 | /** 89 | * Returns JS Call response by emitting internal _jsCallRespone event 90 | */ 91 | NSWebViewinterface.prototype._sendJSCallResponse = function (reqId, response, isError) { 92 | var oResponse = { 93 | reqId: reqId, 94 | response: response || null, 95 | isError: !!isError 96 | }; 97 | this.emit('_jsCallResponse', oResponse); 98 | }; 99 | 100 | /** 101 | * Creates temporary iFrame element to load custom url, for sending handshake message 102 | * to iOS which is necessary to initiate data transfer from webView to iOS 103 | */ 104 | NSWebViewinterface.prototype._createIFrame = function (src) { 105 | var rootElm = document.documentElement; 106 | var newFrameElm = document.createElement("IFRAME"); 107 | newFrameElm.setAttribute("src", src); 108 | rootElm.appendChild(newFrameElm); 109 | return newFrameElm; 110 | }; 111 | 112 | /** 113 | * Sends handshaking signal to iOS using custom url, for sending event payload or JS Call response. 114 | * As iOS do not allow to send any data from webView. Here we are sending data in two steps. 115 | * 1. Send handshake signal, by loading custom url in iFrame with metadata (eventName, unique responseId) 116 | * 2. On intercept of this request, iOS calls _getIOSResponse with the responseId to fetch the data. 117 | */ 118 | NSWebViewinterface.prototype._emitEventToIOS = function (eventName, data) { 119 | this._iosResponseMap[++this._iosCntResponseId] = data; 120 | var metadata = { eventName: eventName, resId: this._iosCntResponseId }; 121 | var url = 'js2ios:' + JSON.stringify(metadata); 122 | var iFrame = this._createIFrame(url); 123 | iFrame.parentNode.removeChild(iFrame); 124 | }; 125 | 126 | /** 127 | * Returns data to iOS. This function is called from iOS. 128 | */ 129 | NSWebViewinterface.prototype._getIOSResponse = function (resId) { 130 | var response = this._iosResponseMap[resId]; 131 | delete this._iosResponseMap[resId]; 132 | return response; 133 | }; 134 | 135 | /** 136 | * Calls native android function to emit event and payload to android 137 | */ 138 | NSWebViewinterface.prototype._emitEventToAndroid = function (eventName, data) { 139 | window.androidWebViewInterface.handleEventFromWebView(eventName, data); 140 | }; 141 | 142 | /** 143 | * Registers handlers for android/ios event/command 144 | */ 145 | NSWebViewinterface.prototype.on = function (eventName, callback) { 146 | var lstListeners = this.eventListenerMap[eventName] || (this.eventListenerMap[eventName] = []); 147 | lstListeners.push(callback); 148 | }; 149 | 150 | /** 151 | * Emits event to android/ios 152 | */ 153 | NSWebViewinterface.prototype.emit = function (eventName, data) { 154 | var strData = typeof data === 'object' ? JSON.stringify(data) : data; 155 | if (window.androidWebViewInterface) { 156 | this._emitEventToAndroid(eventName, strData); 157 | } 158 | else { 159 | this._emitEventToIOS(eventName, strData); 160 | } 161 | }; 162 | return NSWebViewinterface; 163 | })(); 164 | window.nsWebViewInterface = new NSWebViewinterface(); 165 | -------------------------------------------------------------------------------- /docs/Roadmap.md: -------------------------------------------------------------------------------- 1 | 2 | This is an extremely rough outline of the needed features. Items with a check 3 | are currently functional, although they may need some design help. 4 | 5 | ## Pages 6 | 7 | ### Login ✓ 8 | 9 | * Using Screeps API ✓ 10 | 11 | 12 | ### Performance 13 | 14 | * Auto updating stats- 15 | * CPU 16 | * Bucket 17 | * Memory 18 | 19 | 20 | ### Overview (home) 21 | 22 | * Formatting 23 | * Username ✓ 24 | * Badge ✓ 25 | * Credits ✓ 26 | * GCL - Current Level ✓ 27 | * GCL - Current Total ✓ 28 | * GCL - Tracking (current / next level) ✓ 29 | * GCL - Progress Bar 30 | 31 | * Power - Current Level ✓ 32 | * Power - Current Total ✓ 33 | * Power - Tracking (current / next level) ✓ 34 | * Power - Progress Bar 35 | 36 | * Number of Rooms ✓ 37 | 38 | * Control Ranking ✓ 39 | * Power Ranking ✓ 40 | 41 | ### Rooms 42 | 43 | * Listing - build graphics? 44 | * RCL 45 | * RCL Progress (if below RCL8) 46 | 47 | 48 | ### Market 49 | 50 | * List of Resources 51 | * Subpage for each resource. 52 | * Buy Orders 53 | * Sell Orders 54 | * Averages 55 | 56 | 57 | ### Orders ✓ 58 | 59 | * List of Orders ✓ 60 | * Slide to cancel ✓ 61 | * Actually cancel order (via console api) ✓ 62 | 63 | 64 | ### Wallet ✓ 65 | 66 | * History of Transactions ✓ 67 | * Multiple Page Tracking ✓ 68 | * Transaction Detail Page ✓ 69 | 70 | 71 | ### Messenger ✓ 72 | 73 | * Index ✓ 74 | * Conversation Page ✓ 75 | * Reply to conversation ✓ 76 | * New Conversation ✓ 77 | 78 | 79 | ### Console 80 | 81 | * Read console results. ✓ 82 | * Display console output. ✓ 83 | * Support HTML displays. ✓ 84 | * Submit console commands. ✓ 85 | 86 | * Silence screeps-stats. ✓ 87 | 88 | * Add "interactive" mode that suppresses `log`. 89 | * Use CSS - allow "log" and "error" fields to be toggled 90 | 91 | * React to application state. ✓ 92 | * suspend/exit - kill websockets. ✓ 93 | * resume - restart websockets. ✓ 94 | * leave page - kill websockets. ✓ 95 | 96 | 97 | ### Alliances ✓ 98 | 99 | * Listing of Alliances ✓ 100 | * Include images from Leage website. ✓ 101 | 102 | * Alliance Subpage ✓ 103 | * Members ✓ 104 | * Ranking Data ✓ 105 | 106 | 107 | ### Alliance Rankings 108 | 109 | ### User Leaderboards 110 | 111 | * Control Rankings 112 | * Power Rankings 113 | 114 | ### Server Status ✓ 115 | 116 | * Average Tick Time ✓ 117 | * Current Tick ✓ 118 | -------------------------------------------------------------------------------- /hooks/after-prepare/nativescript-dev-android-snapshot.js: -------------------------------------------------------------------------------- 1 | module.exports = require("nativescript-dev-android-snapshot/hooks/after-prepare-hook.js"); 2 | -------------------------------------------------------------------------------- /hooks/before-prepare/nativescript-dev-android-snapshot.js: -------------------------------------------------------------------------------- 1 | module.exports = require("nativescript-dev-android-snapshot/hooks/before-prepare-hook.js"); 2 | -------------------------------------------------------------------------------- /hooks/before-prepare/nativescript-nodeify.js: -------------------------------------------------------------------------------- 1 | module.exports = require("nativescript-nodeify/patch-npm-packages.js"); 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "NativeScript Application", 3 | "license": "MIT", 4 | "readme": "NativeScript Application", 5 | "repository": "", 6 | "nativescript": { 7 | "id": "org.screepers.Spawn1", 8 | "tns-android": { 9 | "version": "2.5.0" 10 | }, 11 | "tns-ios": { 12 | "version": "2.5.0" 13 | } 14 | }, 15 | "dependencies": { 16 | "events": "^1.1.1", 17 | "https": "^1.0.0", 18 | "lodash": "^4.17.4", 19 | "nativescript-canvas-interface": "^1.0.0", 20 | "nativescript-iqkeyboardmanager": "^1.0.1", 21 | "nativescript-nodeify": "^0.5.3", 22 | "nativescript-telerik-ui": "^1.6.1", 23 | "nativescript-theme-core": "~1.0.2", 24 | "nativescript-web-image-cache": "^3.4.0", 25 | "nativescript-websockets": "^1.3.1", 26 | "request": "^2.81.0", 27 | "tns-core-modules": "2.5.0", 28 | "url": "^0.11.0", 29 | "util": "^0.10.3", 30 | "ws": "^2.2.1" 31 | }, 32 | "devDependencies": { 33 | "babel-traverse": "6.23.1", 34 | "babel-types": "6.23.0", 35 | "babylon": "6.16.1", 36 | "lazy": "1.0.11", 37 | "nativescript-dev-android-snapshot": "^0.*.*" 38 | } 39 | } 40 | --------------------------------------------------------------------------------