├── app
├── images
│ └── .gitkeep
├── views
│ ├── about
│ │ ├── about.css
│ │ ├── about.js
│ │ └── about.xml
│ ├── login
│ │ ├── login.css
│ │ ├── login.xml
│ │ └── login.js
│ ├── orders
│ │ ├── orders.css
│ │ ├── orders.xml
│ │ └── orders.js
│ ├── server
│ │ ├── server.css
│ │ ├── server.js
│ │ └── server.xml
│ ├── wallet
│ │ ├── wallet.css
│ │ ├── transaction.css
│ │ ├── transaction.js
│ │ ├── wallet.xml
│ │ ├── transaction.xml
│ │ └── wallet.js
│ ├── alliance
│ │ ├── alliance.css
│ │ ├── members.js
│ │ ├── members.xml
│ │ ├── alliance.js
│ │ └── alliance.xml
│ ├── alliances
│ │ ├── alliances.css
│ │ ├── alliances.xml
│ │ └── alliances.js
│ ├── messages
│ │ ├── messages.css
│ │ ├── conversation.css
│ │ ├── messages.xml
│ │ ├── conversation.xml
│ │ ├── conversation.js
│ │ └── messages.js
│ ├── category_template
│ │ ├── template.css
│ │ ├── template.js
│ │ └── template.xml
│ ├── profile
│ │ ├── profile.css
│ │ ├── profile.js
│ │ └── profile.xml
│ └── console
│ │ ├── console.css
│ │ ├── console.xml
│ │ └── console.js
├── package.json
├── platform.ios.css
├── App_Resources
│ ├── iOS
│ │ ├── logo.png
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── icon.png
│ │ │ │ ├── icon-120.png
│ │ │ │ ├── icon-29.png
│ │ │ │ ├── icon-40.png
│ │ │ │ ├── icon-50.png
│ │ │ │ ├── icon-57.png
│ │ │ │ ├── icon-60.png
│ │ │ │ ├── icon-72.png
│ │ │ │ ├── icon-76.png
│ │ │ │ ├── icon-29@2x.png
│ │ │ │ ├── icon-29@3x.png
│ │ │ │ ├── icon-40@2x.png
│ │ │ │ ├── icon-40@3x.png
│ │ │ │ ├── icon-50@2x.png
│ │ │ │ ├── icon-57@2x.png
│ │ │ │ ├── icon-57@3x.png
│ │ │ │ ├── icon-60@2x.png
│ │ │ │ ├── icon-60@3x.png
│ │ │ │ ├── icon-72@2x.png
│ │ │ │ ├── icon-72@3x.png
│ │ │ │ ├── icon-76@2x.png
│ │ │ │ ├── icon-76@3x.png
│ │ │ │ ├── icon-Small.png
│ │ │ │ ├── iTunesArtwork.png
│ │ │ │ ├── icon-83.5@2x.png
│ │ │ │ ├── icon-Small@2x.png
│ │ │ │ ├── icon-Small@3x.png
│ │ │ │ ├── iTunesArtwork@2x.png
│ │ │ │ └── Contents.json
│ │ │ ├── LaunchImage.launchimage
│ │ │ │ ├── Default.png
│ │ │ │ ├── Default@2x.png
│ │ │ │ ├── Default-568h@2x.png
│ │ │ │ ├── Default-667h@2x.png
│ │ │ │ ├── Default-736h@3x.png
│ │ │ │ ├── Default-Portrait.png
│ │ │ │ ├── Default-Landscape.png
│ │ │ │ ├── Default-Landscape@2x.png
│ │ │ │ ├── Default-Landscape@3x.png
│ │ │ │ ├── Default-Portrait@2x.png
│ │ │ │ └── Contents.json
│ │ │ ├── LaunchScreen.Center.imageset
│ │ │ │ ├── LaunchScreen-Center.png
│ │ │ │ ├── LaunchScreen-Center@2x.png
│ │ │ │ └── Contents.json
│ │ │ └── LaunchScreen.AspectFill.imageset
│ │ │ │ ├── LaunchScreen-AspectFill.png
│ │ │ │ ├── LaunchScreen-AspectFill@2x.png
│ │ │ │ └── Contents.json
│ │ ├── build.xcconfig
│ │ ├── Info.plist
│ │ └── LaunchScreen.storyboard
│ └── Android
│ │ ├── playstore-icon.png
│ │ ├── drawable-hdpi
│ │ ├── icon.png
│ │ ├── logo.png
│ │ └── background.png
│ │ ├── drawable-ldpi
│ │ ├── icon.png
│ │ ├── logo.png
│ │ └── background.png
│ │ ├── drawable-mdpi
│ │ ├── icon.png
│ │ ├── logo.png
│ │ └── background.png
│ │ ├── drawable-xhdpi
│ │ ├── icon.png
│ │ ├── logo.png
│ │ └── background.png
│ │ ├── drawable-xxhdpi
│ │ ├── icon.png
│ │ ├── logo.png
│ │ └── background.png
│ │ ├── drawable-xxxhdpi
│ │ ├── icon.png
│ │ ├── logo.png
│ │ └── background.png
│ │ ├── values-v21
│ │ ├── colors.xml
│ │ └── styles.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ └── styles.xml
│ │ ├── drawable-nodpi
│ │ └── splash_screen.xml
│ │ ├── app.gradle
│ │ └── AndroidManifest.xml
├── fonts
│ └── fontawesome-webfont.ttf
├── platform.android.css
├── README.md
├── shared
│ ├── widgets
│ │ ├── header.xml
│ │ └── navigation.xml
│ └── navtools.js
├── prototypes
│ └── numbers.js
├── app.js
├── services
│ ├── league.js
│ ├── session.js
│ └── screeps.js
├── app.css
└── www
│ └── lib
│ ├── nativescript-canvas-interface.js
│ ├── nativescript-webview-interface.js
│ └── es6-promise.min.js
├── hooks
├── before-prepare
│ ├── nativescript-nodeify.js
│ └── nativescript-dev-android-snapshot.js
└── after-prepare
│ └── nativescript-dev-android-snapshot.js
├── README.md
├── .gitignore
├── Makefile
├── LICENSE
├── package.json
└── docs
└── Roadmap.md
/app/images/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/about/about.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/login/login.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/orders/orders.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/server/server.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/wallet/wallet.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/alliance/alliance.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/alliances/alliances.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/messages/messages.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/wallet/transaction.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/category_template/template.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/profile/profile.css:
--------------------------------------------------------------------------------
1 | .user_header {
2 | margin: 15;
3 | }
--------------------------------------------------------------------------------
/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "app.js",
3 | "name": "spawn1",
4 | "version": "1.0.1"
5 | }
--------------------------------------------------------------------------------
/app/platform.ios.css:
--------------------------------------------------------------------------------
1 | /* From platform.ios.css */
2 | .link {
3 | border-width: 0;
4 | }
5 |
--------------------------------------------------------------------------------
/app/App_Resources/iOS/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/logo.png
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/app/platform.android.css:
--------------------------------------------------------------------------------
1 | /* From platform.android.css */
2 | .link {
3 | background-color: transparent;
4 | }
5 |
--------------------------------------------------------------------------------
/hooks/before-prepare/nativescript-nodeify.js:
--------------------------------------------------------------------------------
1 | module.exports = require("nativescript-nodeify/patch-npm-packages.js");
2 |
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/app/App_Resources/Android/playstore-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/playstore-icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-hdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-hdpi/logo.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-ldpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-ldpi/logo.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-mdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-mdpi/logo.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xhdpi/logo.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xxhdpi/logo.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xxxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xxxhdpi/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xxxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xxxhdpi/logo.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-hdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-hdpi/background.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-ldpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-ldpi/background.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-mdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-mdpi/background.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xhdpi/background.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xxhdpi/background.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/drawable-xxxhdpi/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/Android/drawable-xxxhdpi/background.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/values-v21/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3d5afe
4 |
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-50@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-57@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-72@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-Small@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tedivm/Spawn1/HEAD/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/HEAD/app/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png
--------------------------------------------------------------------------------
/app/App_Resources/Android/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #F5F5F5
4 | #757575
5 | #33B5E5
6 | #272734
7 |
--------------------------------------------------------------------------------
/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/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_Resources/Android/drawable-nodpi/splash_screen.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 |
4 |
5 | -
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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/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.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/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/shared/widgets/header.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/shared/navtools.js:
--------------------------------------------------------------------------------
1 | var Session = require('../services/session.js')
2 | var frame = require('ui/frame');
3 |
4 | exports.onTap = function (args) {
5 | var currentPage = frame.topmost().currentPage;
6 | var linkedPageName = args.view.text.toLowerCase()
7 | var drawer = currentPage.getViewById("drawer");
8 |
9 | if(linkedPageName == 'logout') {
10 | Session.clear()
11 | linkedPageName = 'login'
12 | }
13 |
14 | frame.topmost().navigate({
15 | 'moduleName': "views/" + linkedPageName + "/" + linkedPageName,
16 | 'clearHistory': true
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/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/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/shared/widgets/navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/views/login/login.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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/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/messages/conversation.css:
--------------------------------------------------------------------------------
1 | ListView {
2 | separator-color: transparent;
3 | }
4 |
5 | .p {
6 | margin: 0 0 0 0;
7 | padding: 0;
8 | }
9 |
10 |
11 | .msg {
12 | font-size: 14px;
13 | margin-top: 5px;
14 | margin-bottom: 10;
15 | }
16 |
17 | .me .msg_text {
18 | background-color: #30A9FF;
19 | color: white;
20 | padding: 8px;
21 | margin-left: 40px;
22 | border-radius: 15;
23 |
24 | }
25 |
26 | .them .msg_text {
27 | background-color: #e0e0e0;
28 | color: #333;
29 | padding: 7px;
30 | border-radius: 15;
31 | margin-right: 40px;
32 | }
33 |
34 | .authorimg {
35 | margin: 0px 5px 5px 5px;
36 | width: 30;
37 | height: 30;
38 | border-radius: 15;
39 | }
40 |
41 | .them .msg_timestamp {
42 | color: gray;
43 | font-size: 11px;
44 | margin-left: 40px;
45 | }
46 |
47 | .me .msg_timestamp {
48 | color: gray;
49 | font-size: 11px;
50 | margin-right: 40px;
51 | text-align: right;
52 | }
53 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/app/App_Resources/Android/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
14 |
15 |
16 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/about/about.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/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 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/views/wallet/wallet.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/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/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 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/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/wallet/transaction.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
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 |
--------------------------------------------------------------------------------
/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/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/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/views/profile/profile.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/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/orders/orders.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/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 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/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 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/views/messages/conversation.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/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/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/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/views/messages/conversation.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 processed_messages = []
16 | var pageData = new Observable();
17 |
18 |
19 | var page;
20 | var drawer;
21 |
22 | var conversationTimerID = false
23 | var lastMessageTime = false
24 |
25 |
26 | function loadConversation () {
27 | console.log('loading conversation')
28 | ScreepsAPI.messages_list(page.bindingContext.respondent)
29 | .then(function(data){
30 | var scroll = false
31 | for(var message of data['messages']) {
32 |
33 | if(processed_messages.indexOf(message['_id']) < 0) {
34 | processed_messages.push(message['_id'])
35 |
36 | if(message.type == 'out') {
37 | message.badge_url = League.getBadgeUrl(Session.userdata.username, false)
38 | } else {
39 | message.badge_url = League.getBadgeUrl(page.bindingContext.recipient, false)
40 | }
41 |
42 | var message_date = new Date(message['date']);
43 | lastMessageTime = message_date
44 | message['date_locale'] = message_date.toLocaleString()
45 | items.push(message)
46 | scroll = true
47 | }
48 | }
49 |
50 | // If conversation has new messages scroll to read them.
51 | if(scroll) {
52 | var conversation_list = page.getViewById("conversation_list");
53 | conversation_list.scrollToIndex(items.length - 1); // scroll to the bottom
54 | }
55 |
56 | }).catch(function(err){
57 | console.log(err.message)
58 | console.log(err.trace)
59 | })
60 | }
61 |
62 |
63 | exports.pageLoaded = function(args) {
64 | page = args.object;
65 | var source = {}
66 | drawer = page.getViewById("drawer");
67 | //page.getViewById("title").text = ''
68 | // Additional on load actions here
69 |
70 | pageData.recipient = page.bindingContext.recipient
71 | pageData.respondent = page.bindingContext.respondent
72 |
73 | processed_messages = []
74 | items.length = 0
75 |
76 | page.bindingContext = pageData;
77 | loadConversation()
78 | pageData.set("messages", items);
79 |
80 | conversationTimerID = timer.setInterval(function conversationReloadTimer(){
81 | loadConversation()
82 | if(lastMessageTime) {
83 | // Range between 5 to 90 second delay between reloads.
84 | var elapsed = ((new Date()).getTime() - lastMessageTime.getTime())
85 | var interval = Math.round(Math.max(Math.min(elapsed/10, 90000), 5000))
86 | timer.clearInterval(conversationTimerID)
87 | conversationTimerID = false
88 | conversationTimerID = timer.setInterval(conversationReloadTimer, interval)
89 | }
90 | }, 5000)
91 |
92 | };
93 |
94 | exports.pageUnloaded = function (args) {
95 | if(conversationTimerID !== false) {
96 | timer.clearInterval(conversationTimerID)
97 | conversationTimerID = false
98 | }
99 | }
100 |
101 |
102 | exports.toggleDrawer = function() {
103 | drawer.toggleDrawerState();
104 | };
105 |
106 | exports.itemTemplateSelector = function (item) {
107 | return item.type == 'in' ? 'them' : 'me'
108 | }
109 |
110 | exports.addMessage = function (args) {
111 | var message_input = page.getViewById("message_input")
112 | var message = message_input.text;
113 | console.log('making call to api')
114 | ScreepsAPI.messages_send(page.bindingContext.respondent, message)
115 | .then(function(data){
116 |
117 | message_input.text = ''
118 | loadConversation()
119 | })
120 | .catch(function(err){
121 | console.log(err.message)
122 | console.log(err.stack)
123 | })
124 | }
125 |
--------------------------------------------------------------------------------
/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/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/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/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} 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 |
--------------------------------------------------------------------------------
/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/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