├── .gitignore
├── .idea
├── caches
│ └── build_file_checksums.ser
├── misc.xml
├── modules.xml
└── runConfigurations.xml
├── .travis.yml
├── LICENSE.md
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── rubenwardy
│ │ └── minetestmodmanager
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ │ └── com
│ │ │ └── rubenwardy
│ │ │ └── minetestmodmanager
│ │ │ ├── MyApplication.kt
│ │ │ ├── manager
│ │ │ ├── BCastReceiver.java
│ │ │ ├── ModInstallService.java
│ │ │ ├── ModManager.java
│ │ │ ├── ServiceResultReceiver.java
│ │ │ └── Utils.java
│ │ │ ├── models
│ │ │ ├── Events.java
│ │ │ ├── Game.java
│ │ │ ├── MinetestConf.java
│ │ │ ├── MinetestDepends.java
│ │ │ ├── Mod.java
│ │ │ ├── ModList.java
│ │ │ └── ModSpec.java
│ │ │ ├── presenters
│ │ │ ├── DisclaimerPresenter.kt
│ │ │ └── ModListPresenter.kt
│ │ │ ├── restapi
│ │ │ ├── StoreAPI.java
│ │ │ └── StoreAPIBuilder.java
│ │ │ └── views
│ │ │ ├── DisclaimerActivity.java
│ │ │ ├── InstallDependsDialogFragment.java
│ │ │ ├── ModDetailActivity.java
│ │ │ ├── ModDetailFragment.java
│ │ │ ├── ModInfoDialogFragment.java
│ │ │ ├── ModListActivity.java
│ │ │ ├── ReadmeActivity.java
│ │ │ ├── ReportActivity.java
│ │ │ ├── SectionedRecyclerViewAdapter.java
│ │ │ ├── SettingsAndAboutActivity.kt
│ │ │ ├── SplashActivity.kt
│ │ │ └── WorldConfigActivity.java
│ └── res
│ │ ├── drawable-hdpi-v11
│ │ └── notification_icon.png
│ │ ├── drawable-hdpi-v9
│ │ └── notification_icon.png
│ │ ├── drawable-hdpi
│ │ └── notification_icon.png
│ │ ├── drawable-mdpi-v11
│ │ └── notification_icon.png
│ │ ├── drawable-mdpi-v9
│ │ └── notification_icon.png
│ │ ├── drawable-mdpi
│ │ └── notification_icon.png
│ │ ├── drawable-xhdpi-v11
│ │ └── notification_icon.png
│ │ ├── drawable-xhdpi-v9
│ │ └── notification_icon.png
│ │ ├── drawable-xhdpi
│ │ └── notification_icon.png
│ │ ├── drawable-xxhdpi-v11
│ │ └── notification_icon.png
│ │ ├── drawable-xxhdpi-v9
│ │ └── notification_icon.png
│ │ ├── drawable-xxhdpi
│ │ └── notification_icon.png
│ │ ├── drawable
│ │ ├── background_splash.xml
│ │ ├── ic_mod_action_check_depends_24dp.xml
│ │ ├── ic_mod_action_find_elsewhere_24dp.xml
│ │ ├── ic_mod_action_forum_topic_24dp.xml
│ │ ├── ic_mod_action_info_24dp.xml
│ │ ├── ic_mod_action_mods_by_author.xml
│ │ ├── ic_mod_action_readme_24dp.xml
│ │ ├── ic_mod_action_report_24dp.xml
│ │ ├── ic_public_24dp.xml
│ │ └── mod_preview_circle.xml
│ │ ├── layout
│ │ ├── activity_disclaimer.xml
│ │ ├── activity_mod_detail.xml
│ │ ├── activity_mod_list.xml
│ │ ├── activity_readme.xml
│ │ ├── activity_report.xml
│ │ ├── activity_settingsandabout.xml
│ │ ├── activity_world_config.xml
│ │ ├── depends_list_item.xml
│ │ ├── dialog_mod_information.xml
│ │ ├── fragment_install_depends_dialog.xml
│ │ ├── mod_checklist_content.xml
│ │ ├── mod_detail.xml
│ │ ├── mod_list.xml
│ │ ├── mod_list_content.xml
│ │ ├── mod_list_twopane.xml
│ │ └── section.xml
│ │ ├── menu
│ │ ├── menu_mod_list.xml
│ │ ├── menu_report.xml
│ │ └── menu_world_config.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-cs
│ │ └── strings.xml
│ │ ├── values-de
│ │ └── strings.xml
│ │ ├── values-es
│ │ └── strings.xml
│ │ ├── values-fr
│ │ └── strings.xml
│ │ ├── values-it
│ │ └── strings.xml
│ │ ├── values-ms
│ │ └── strings.xml
│ │ ├── values-night
│ │ └── colors.xml
│ │ ├── values-pl
│ │ └── strings.xml
│ │ ├── values-tr
│ │ └── strings.xml
│ │ ├── values-v21
│ │ └── styles.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ ├── values-w900dp
│ │ └── refs.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── rubenwardy
│ └── minetestmodmanager
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle-app.setting
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── misc
├── logo.svg
├── logo_fancy.svg
└── notification_icon.svg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | *.apk
10 |
11 | # Created by https://www.gitignore.io/api/java,linux,macos,android,windows,intellij,androidstudio
12 | # Edit at https://www.gitignore.io/?templates=java,linux,macos,android,windows,intellij,androidstudio
13 |
14 | ### Android ###
15 | # Built application files
16 | *.apk
17 | *.ap_
18 | *.aab
19 |
20 | # Files for the ART/Dalvik VM
21 | *.dex
22 |
23 | # Java class files
24 | *.class
25 |
26 | # Generated files
27 | bin/
28 | gen/
29 | out/
30 |
31 | # Gradle files
32 | .gradle/
33 | build/
34 |
35 | # Local configuration file (sdk path, etc)
36 | local.properties
37 |
38 | # Proguard folder generated by Eclipse
39 | proguard/
40 |
41 | # Log Files
42 | *.log
43 |
44 | # Android Studio Navigation editor temp files
45 | .navigation/
46 |
47 | # Android Studio captures folder
48 | captures/
49 |
50 | # IntelliJ
51 | *.iml
52 | .idea/workspace.xml
53 | .idea/tasks.xml
54 | .idea/gradle.xml
55 | .idea/assetWizardSettings.xml
56 | .idea/dictionaries
57 | .idea/libraries
58 | .idea/caches
59 | # Android Studio 3 in .gitignore file.
60 | .idea/caches/build_file_checksums.ser
61 | .idea/modules.xml
62 |
63 | # Keystore files
64 | # Uncomment the following lines if you do not want to check your keystore files in.
65 | #*.jks
66 | #*.keystore
67 |
68 | # External native build folder generated in Android Studio 2.2 and later
69 | .externalNativeBuild
70 |
71 | # Google Services (e.g. APIs or Firebase)
72 | # google-services.json
73 |
74 | # Freeline
75 | freeline.py
76 | freeline/
77 | freeline_project_description.json
78 |
79 | # fastlane
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots
83 | fastlane/test_output
84 | fastlane/readme.md
85 |
86 | # Version control
87 | vcs.xml
88 |
89 | # lint
90 | lint/intermediates/
91 | lint/generated/
92 | lint/outputs/
93 | lint/tmp/
94 | # lint/reports/
95 |
96 | ### Android Patch ###
97 | gen-external-apklibs
98 | output.json
99 |
100 | ### AndroidStudio ###
101 | # Covers files to be ignored for android development using Android Studio.
102 |
103 | # Built application files
104 |
105 | # Files for the ART/Dalvik VM
106 |
107 | # Java class files
108 |
109 | # Generated files
110 |
111 | # Gradle files
112 | .gradle
113 |
114 | # Signing files
115 | .signing/
116 |
117 | # Local configuration file (sdk path, etc)
118 |
119 | # Proguard folder generated by Eclipse
120 |
121 | # Log Files
122 |
123 | # Android Studio
124 | /*/build/
125 | /*/local.properties
126 | /*/out
127 | /*/*/build
128 | /*/*/production
129 | *.ipr
130 | *~
131 | *.swp
132 |
133 | # Android Patch
134 |
135 | # External native build folder generated in Android Studio 2.2 and later
136 |
137 | # NDK
138 | obj/
139 |
140 | # IntelliJ IDEA
141 | *.iws
142 | /out/
143 |
144 | # User-specific configurations
145 | .idea/caches/
146 | .idea/libraries/
147 | .idea/shelf/
148 | .idea/.name
149 | .idea/compiler.xml
150 | .idea/copyright/profiles_settings.xml
151 | .idea/encodings.xml
152 | .idea/misc.xml
153 | .idea/scopes/scope_settings.xml
154 | .idea/vcs.xml
155 | .idea/jsLibraryMappings.xml
156 | .idea/datasources.xml
157 | .idea/dataSources.ids
158 | .idea/sqlDataSources.xml
159 | .idea/dynamic.xml
160 | .idea/uiDesigner.xml
161 |
162 | # OS-specific files
163 | .DS_Store
164 | .DS_Store?
165 | ._*
166 | .Spotlight-V100
167 | .Trashes
168 | ehthumbs.db
169 | Thumbs.db
170 |
171 | # Legacy Eclipse project files
172 | .classpath
173 | .project
174 | .cproject
175 | .settings/
176 |
177 | # Mobile Tools for Java (J2ME)
178 | .mtj.tmp/
179 |
180 | # Package Files #
181 | *.war
182 | *.ear
183 |
184 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
185 | hs_err_pid*
186 |
187 | ## Plugin-specific files:
188 |
189 | # mpeltonen/sbt-idea plugin
190 | .idea_modules/
191 |
192 | # JIRA plugin
193 | atlassian-ide-plugin.xml
194 |
195 | # Mongo Explorer plugin
196 | .idea/mongoSettings.xml
197 |
198 | # Crashlytics plugin (for Android Studio and IntelliJ)
199 | com_crashlytics_export_strings.xml
200 | crashlytics.properties
201 | crashlytics-build.properties
202 | fabric.properties
203 |
204 | ### AndroidStudio Patch ###
205 |
206 | !/gradle/wrapper/gradle-wrapper.jar
207 |
208 | ### Intellij ###
209 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
210 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
211 |
212 | # User-specific stuff
213 | .idea/**/workspace.xml
214 | .idea/**/tasks.xml
215 | .idea/**/usage.statistics.xml
216 | .idea/**/dictionaries
217 | .idea/**/shelf
218 |
219 | # Generated files
220 | .idea/**/contentModel.xml
221 |
222 | # Sensitive or high-churn files
223 | .idea/**/dataSources/
224 | .idea/**/dataSources.ids
225 | .idea/**/dataSources.local.xml
226 | .idea/**/sqlDataSources.xml
227 | .idea/**/dynamic.xml
228 | .idea/**/uiDesigner.xml
229 | .idea/**/dbnavigator.xml
230 |
231 | # Gradle
232 | .idea/**/gradle.xml
233 | .idea/**/libraries
234 |
235 | # Gradle and Maven with auto-import
236 | # When using Gradle or Maven with auto-import, you should exclude module files,
237 | # since they will be recreated, and may cause churn. Uncomment if using
238 | # auto-import.
239 | # .idea/modules.xml
240 | # .idea/*.iml
241 | # .idea/modules
242 |
243 | # CMake
244 | cmake-build-*/
245 |
246 | # Mongo Explorer plugin
247 | .idea/**/mongoSettings.xml
248 |
249 | # File-based project format
250 |
251 | # IntelliJ
252 |
253 | # mpeltonen/sbt-idea plugin
254 |
255 | # JIRA plugin
256 |
257 | # Cursive Clojure plugin
258 | .idea/replstate.xml
259 |
260 | # Crashlytics plugin (for Android Studio and IntelliJ)
261 |
262 | # Editor-based Rest Client
263 | .idea/httpRequests
264 |
265 | # Android studio 3.1+ serialized cache file
266 |
267 | # JetBrains templates
268 | **___jb_tmp___
269 |
270 | ### Intellij Patch ###
271 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
272 |
273 | # *.iml
274 | # modules.xml
275 | # .idea/misc.xml
276 | # *.ipr
277 |
278 | # Sonarlint plugin
279 | .idea/sonarlint
280 |
281 | ### Java ###
282 | # Compiled class file
283 |
284 | # Log file
285 |
286 | # BlueJ files
287 | *.ctxt
288 |
289 | # Mobile Tools for Java (J2ME)
290 |
291 | # Package Files #
292 | *.jar
293 | *.nar
294 | *.zip
295 | *.tar.gz
296 | *.rar
297 |
298 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
299 |
300 | ### Linux ###
301 |
302 | # temporary files which can be created if a process still has a handle open of a deleted file
303 | .fuse_hidden*
304 |
305 | # KDE directory preferences
306 | .directory
307 |
308 | # Linux trash folder which might appear on any partition or disk
309 | .Trash-*
310 |
311 | # .nfs files are created when an open file is removed but is still being accessed
312 | .nfs*
313 |
314 | ### macOS ###
315 | # General
316 | .AppleDouble
317 | .LSOverride
318 |
319 | # Icon must end with two \r
320 | Icon
321 |
322 | # Thumbnails
323 |
324 | # Files that might appear in the root of a volume
325 | .DocumentRevisions-V100
326 | .fseventsd
327 | .TemporaryItems
328 | .VolumeIcon.icns
329 | .com.apple.timemachine.donotpresent
330 |
331 | # Directories potentially created on remote AFP share
332 | .AppleDB
333 | .AppleDesktop
334 | Network Trash Folder
335 | Temporary Items
336 | .apdisk
337 |
338 | ### Windows ###
339 | # Windows thumbnail cache files
340 | ehthumbs_vista.db
341 |
342 | # Dump file
343 | *.stackdump
344 |
345 | # Folder config file
346 | [Dd]esktop.ini
347 |
348 | # Recycle Bin used on file shares
349 | $RECYCLE.BIN/
350 |
351 | # Windows Installer files
352 | *.cab
353 | *.msi
354 | *.msix
355 | *.msm
356 | *.msp
357 |
358 | # Windows shortcuts
359 | *.lnk
360 |
361 | # End of https://www.gitignore.io/api/java,linux,macos,android,windows,intellij,androidstudio
362 |
363 |
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
22 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | sudo: false
3 | android:
4 | components:
5 | - tools
6 | - build-tools-25.0.2
7 | - android-25
8 | - extra-android-support
9 | - extra-google-m2repository
10 | - extra-android-m2repository
11 | - platform-tools
12 | script: ./gradlew build test
13 | jdk: oraclejdk8
14 | os:
15 | - linux
16 | notifications:
17 | email: false
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Minetest Mods for Android
2 |
3 | [](https://travis-ci.org/rubenwardy/mtmods4android)
4 | [](https://hosted.weblate.org/projects/minetest/mtmods4android/)
5 | 
6 | [](https://github.com/rubenwardy/mtmods4android/releases)
7 | 
8 |
9 | A mod manager for Android. Used as a project to learn the Android SDK.
10 |
11 | Created by [rubenwardy](http://rubenwardy.com). [Backend](http://app-mtmm.rubenwardy.com)
12 |
13 |
14 |
15 |
16 |
17 |
18 | # License
19 |
20 | Minetest Mods for Android
21 | Copyright (C) 2016-2017 rubenwardy
22 |
23 | This program is free software: you can redistribute it and/or modify
24 | it under the terms of the GNU General Public License as published by
25 | the Free Software Foundation, either version 3 of the License, or
26 | (at your option) any later version.
27 |
28 | This program is distributed in the hope that it will be useful,
29 | but WITHOUT ANY WARRANTY; without even the implied warranty of
30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 | GNU General Public License for more details.
32 |
33 | You should have received a copy of the GNU General Public License
34 | along with this program. If not, see .
35 |
36 |
37 | ## Exceptions
38 |
39 | All resources which feature the Minetest logo, such as the notification icon and the launcher icon,
40 | are licensed under CC-BY-SA 3.0. The original author is erlehmann.
41 |
42 | The following are from the Android material design asset studio, and are CC-BY 4.0:
43 |
44 | * app/src/main/res/drawable/ic_public_24dp.xml
45 | * app/src/main/res/drawable/ic_report_problem_24dp.xml
46 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 |
5 | android {
6 | compileSdkVersion 28
7 | buildToolsVersion "28.0.3"
8 | defaultConfig {
9 | applicationId "com.rubenwardy.minetestmodmanager"
10 | minSdkVersion 14
11 | targetSdkVersion 28
12 | versionCode 23
13 | versionName "1.9.1"
14 | buildConfigField "boolean", "ENABLE_RATE_ME", "false"
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled true
19 | shrinkResources true
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 |
22 | lintOptions {
23 | disable 'MissingTranslation'
24 | }
25 | }
26 | }
27 | lintOptions {
28 | abortOnError false
29 | }
30 | }
31 |
32 | dependencies {
33 | implementation fileTree(include: ['*.jar'], dir: 'libs')
34 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
35 | implementation 'com.android.support:appcompat-v7:28.0.0'
36 | implementation 'com.android.support:support-v4:28.0.0'
37 | implementation 'com.android.support:recyclerview-v7:28.0.0'
38 | implementation 'com.android.support:design:28.0.0'
39 | implementation 'com.futuremind.recyclerfastscroll:fastscroll:0.2.5'
40 | implementation 'com.squareup.retrofit2:retrofit:2.5.0'
41 | implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
42 | implementation 'org.greenrobot:eventbus:3.1.1'
43 | implementation 'com.squareup.picasso:picasso:2.71828'
44 | testImplementation 'junit:junit:4.12'
45 | }
46 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\ruben\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | -keep class android.support.** { *; }
20 | -keep interface android.support.** { *; }
21 | -dontwarn okio.**
22 |
23 | -keepattributes SourceFile,LineNumberTable
24 | -keep class com.parse.*{ *; }
25 | -dontwarn com.parse.**
26 | -dontwarn com.squareup.picasso.**
27 | -keepclasseswithmembernames class * {
28 | native ;
29 | }
30 |
31 | # Platform calls Class.forName on types which do not exist on Android to determine platform.
32 | -dontnote retrofit2.Platform
33 | # Platform used when running on RoboVM on iOS. Will not be used at runtime.
34 | -dontnote retrofit2.Platform$IOS$MainThreadExecutor
35 | # Platform used when running on Java 8 VMs. Will not be used at runtime.
36 | -dontwarn retrofit2.Platform$Java8
37 | # Retain generic type information for use by reflection by converters and adapters.
38 | -keepattributes Signature
39 | # Retain declared checked exceptions for use by a Proxy instance.
40 | -keepattributes Exceptions
41 |
42 | -keepattributes *Annotation*
43 | -keepclassmembers class ** {
44 | @org.greenrobot.eventbus.Subscribe ;
45 | }
46 | -keep enum org.greenrobot.eventbus.ThreadMode { *; }
47 |
48 | # Obfuscation breaks GSON
49 | -dontobfuscate
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/rubenwardy/minetestmodmanager/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
17 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
41 |
44 |
45 |
50 |
53 |
54 |
58 |
61 |
62 |
67 |
70 |
71 |
75 |
78 |
79 |
83 |
86 |
87 |
88 |
91 |
92 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/MyApplication.kt:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager
2 |
3 | import android.app.Activity
4 | import android.app.Application
5 | import android.content.Context
6 | import android.support.v7.app.AppCompatDelegate
7 | import com.rubenwardy.minetestmodmanager.views.DisclaimerActivity
8 |
9 | class MyApplication : Application() {
10 | override fun onCreate() {
11 | super.onCreate()
12 |
13 | val theme = getSharedPreferences(DisclaimerActivity.PREFS_NAME, 0).getInt("theme", 0)
14 | AppCompatDelegate.setDefaultNightMode(themeToDayNightMode(theme))
15 | }
16 | }
17 |
18 | fun themeToDayNightMode(themeId: Int): Int {
19 | if (themeId == 0) {
20 | return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
21 | } else if (themeId == 1) {
22 | return AppCompatDelegate.MODE_NIGHT_NO
23 | } else if (themeId == 2) {
24 | return AppCompatDelegate.MODE_NIGHT_YES
25 | } else {
26 | return AppCompatDelegate.MODE_NIGHT_AUTO
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/manager/BCastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.manager;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | public class BCastReceiver extends BroadcastReceiver {
8 | public static final String ACTION_STOP_SERVICE = "stop_service";
9 |
10 | public BCastReceiver() {
11 | }
12 |
13 | @Override
14 | public void onReceive(Context context, Intent intent) {
15 | switch (intent.getAction()) {
16 | case ACTION_STOP_SERVICE:
17 | ModManager modman = ModManager.getInstance();
18 | modman.cancelAsyncTask();
19 | break;
20 | default:
21 | throw new UnsupportedOperationException("Not yet implemented");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/manager/ServiceResultReceiver.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.manager;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.os.ResultReceiver;
9 | import android.util.Log;
10 |
11 | import com.rubenwardy.minetestmodmanager.models.Events;
12 | import com.rubenwardy.minetestmodmanager.models.ModList;
13 |
14 | import org.greenrobot.eventbus.EventBus;
15 |
16 | /**
17 | * Receive a result from the service
18 | */
19 | @SuppressLint("ParcelCreator")
20 | class ServiceResultReceiver extends ResultReceiver {
21 | ServiceResultReceiver(Handler handler) {
22 | super(handler);
23 | }
24 |
25 | private void handleInstall(@NonNull Bundle b, @Nullable String modname, @Nullable String listname) {
26 | if (b.containsKey(ModInstallService.RET_ERROR)) {
27 | final String error = b.getString(ModInstallService.RET_ERROR);
28 | EventBus.getDefault().post(new Events.ModInstallEvent(modname, null, listname, error));
29 | } else {
30 | ModManager modman = ModManager.getInstance();
31 | ModList list = modman.getModList(listname);
32 | if (list != null) {
33 | list.valid = false;
34 | }
35 |
36 | modman.updateLocalModList(list);
37 |
38 | EventBus.getDefault().post(
39 | new Events.ModInstallEvent(modname, listname + "/" + modname, listname, ""));
40 | }
41 | }
42 |
43 | private void handleUninstall(@NonNull Bundle b, @Nullable String modname, @Nullable String listname) {
44 | if (b.containsKey(ModInstallService.RET_ERROR)) {
45 | final String error = b.getString(ModInstallService.RET_ERROR);
46 | EventBus.getDefault().post(new Events.ModUninstallEvent(modname, null, listname, error));
47 | } else {
48 | ModManager modman = ModManager.getInstance();
49 | ModList list = modman.getModList(listname);
50 | if (list != null) {
51 | list.valid = false;
52 | }
53 |
54 | EventBus.getDefault().post(
55 | new Events.ModUninstallEvent(modname, listname + "/" + modname, listname, ""));
56 | }
57 | }
58 |
59 | @Override
60 | protected void onReceiveResult(int resultCode, @NonNull Bundle b) {
61 | String modname = b.getString(ModInstallService.RET_NAME);
62 | String dest = b.getString(ModInstallService.RET_DEST);
63 | String action = b.getString(ModInstallService.RET_ACTION);
64 | if (action == null) {
65 | Log.e("SRR", "Invalid null action");
66 | return;
67 | }
68 |
69 | switch (action) {
70 | case ModInstallService.ACTION_INSTALL:
71 | handleInstall(b, modname, dest);
72 | break;
73 | case ModInstallService.ACTION_UNINSTALL:
74 | handleUninstall(b, modname, dest);
75 | break;
76 | default:
77 | Log.e("SRR", "Unknown service action");
78 | break;
79 | }
80 | }
81 |
82 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/manager/Utils.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.manager;
2 |
3 | import android.support.annotation.CheckResult;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.util.Log;
7 |
8 | import com.rubenwardy.minetestmodmanager.models.Mod;
9 |
10 | import java.io.BufferedInputStream;
11 | import java.io.BufferedReader;
12 | import java.io.File;
13 | import java.io.FileInputStream;
14 | import java.io.FileNotFoundException;
15 | import java.io.FileOutputStream;
16 | import java.io.FileReader;
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.io.OutputStream;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 | import java.util.zip.ZipEntry;
23 | import java.util.zip.ZipInputStream;
24 |
25 | /**
26 | * Mod utility library
27 | */
28 | public class Utils {
29 | public interface UnzipFile_Progress
30 | {
31 | void Progress(long done, long total, String FileName);
32 | }
33 |
34 | @CheckResult
35 | public static boolean UnzipFile(@NonNull File zipFile, File targetDirectory, @Nullable UnzipFile_Progress progress)
36 | throws IOException {
37 | long total_len = zipFile.length();
38 | long total_installed_len = 0;
39 |
40 | ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)));
41 | try {
42 | ZipEntry ze;
43 | int count;
44 | byte[] buffer = new byte[8192];
45 | while ((ze = zis.getNextEntry()) != null) {
46 | if (progress != null) {
47 | total_installed_len += ze.getCompressedSize();
48 | String file_name = ze.getName();
49 | progress.Progress(total_installed_len, total_len, file_name);
50 | }
51 |
52 | File file = new File(targetDirectory, ze.getName());
53 | File dir = ze.isDirectory() ? file : file.getParentFile();
54 | if (!dir.isDirectory() && !dir.mkdirs())
55 | throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath());
56 | if (ze.isDirectory())
57 | continue;
58 | FileOutputStream fout = new FileOutputStream(file);
59 | try {
60 | while ((count = zis.read(buffer)) != -1)
61 | fout.write(buffer, 0, count);
62 | } finally {
63 | fout.close();
64 | }
65 | }
66 | } catch (Exception e) {
67 | return false;
68 | } finally {
69 | zis.close();
70 | }
71 | return true;
72 | }
73 |
74 | @Nullable
75 | public static String readTextFile(@Nullable File file) {
76 | if (file == null) {
77 | return null;
78 | }
79 |
80 | try {
81 | StringBuilder text = new StringBuilder();
82 | BufferedReader br = new BufferedReader(new FileReader(file));
83 | String line;
84 | while ((line = br.readLine()) != null) {
85 | text.append(line);
86 | text.append('\n');
87 | }
88 | br.close();
89 | return text.toString();
90 | } catch (IOException e) {
91 | e.printStackTrace();
92 | return null;
93 | }
94 | }
95 |
96 | @Nullable
97 | public static String checkReadTextFile(@Nullable File file) {
98 | if (file != null && file.isFile()) {
99 | String text = Utils.readTextFile(file);
100 | if (text == null) {
101 | return null;
102 | } else {
103 | text = text.trim();
104 | return text;
105 | }
106 | } else {
107 | return null;
108 | }
109 | }
110 |
111 | @NonNull
112 | public static File getTmpPath(File cachedir, String fileext) {
113 | File file;
114 | int i = 0;
115 | do {
116 | file = new File(cachedir, "tmp" + Integer.toString(i) + fileext);
117 | i++;
118 | } while (file.exists());
119 | return file;
120 | }
121 |
122 | public static void deleteRecursive(@NonNull File fileOrDir) {
123 | if (fileOrDir.isDirectory()) {
124 | for (File child : fileOrDir.listFiles()) {
125 | deleteRecursive(child);
126 | }
127 | }
128 | if (!fileOrDir.delete()) {
129 | Log.e("utils", "Failed to delete path: " + fileOrDir.getAbsolutePath());
130 | }
131 | }
132 |
133 | public static boolean copyFolder(@NonNull File src, @NonNull File dest)
134 | throws IOException{
135 |
136 | if (src.isDirectory()) {
137 | if (!dest.exists()) {
138 | if (!dest.mkdir()) {
139 | return false;
140 | }
141 | }
142 |
143 | for (String file : src.list()) {
144 | File srcFile = new File(src, file);
145 | File destFile = new File(dest, file);
146 |
147 | if (!copyFolder(srcFile,destFile))
148 | return false;
149 | }
150 | } else {
151 | InputStream in = new FileInputStream(src);
152 | OutputStream out = new FileOutputStream(dest);
153 | byte[] buffer = new byte[1024];
154 |
155 | int length;
156 | while ((length = in.read(buffer)) > 0){
157 | out.write(buffer, 0, length);
158 | }
159 |
160 | in.close();
161 | out.close();
162 | }
163 |
164 | return true;
165 | }
166 |
167 | @NonNull
168 | public static Mod.ModType detectModType(@NonNull File file) {
169 | if (new File(file.getAbsolutePath(), "init.lua").exists()) {
170 | return Mod.ModType.EMT_MOD;
171 | } else if (new File(file.getAbsolutePath(), "modpack.txt").exists()) {
172 | return Mod.ModType.EMT_MODPACK;
173 | } else {
174 | return Mod.ModType.EMT_INVALID;
175 | }
176 | }
177 |
178 | @Nullable
179 | public static File findRootDir(@NonNull File dir) {
180 | if (!dir.isDirectory()) {
181 | return null;
182 | }
183 |
184 | Mod.ModType type = detectModType(dir);
185 | if (type == Mod.ModType.EMT_INVALID) {
186 | File subdir = null;
187 | for (File child : dir.listFiles()) {
188 | if (child.isDirectory()) {
189 | if (subdir == null) {
190 | subdir = child;
191 | } else {
192 | return null;
193 | }
194 | }
195 | }
196 | if (subdir == null) {
197 | return null;
198 | } else {
199 | return findRootDir(subdir);
200 | }
201 | } else {
202 | return dir;
203 | }
204 | }
205 |
206 | @Nullable
207 | public static File getReadmePath(@NonNull File folder) {
208 | List files = new ArrayList<>();
209 | files.add(new File(folder, "readme.md"));
210 | files.add(new File(folder, "readme.txt"));
211 | files.add(new File(folder, "README.md"));
212 | files.add(new File(folder, "README.txt"));
213 | for (File file : files) {
214 | if (file.exists() && file.isFile()) {
215 | return file;
216 | }
217 | }
218 | return null;
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/Events.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.graphics.drawable.Drawable;
4 |
5 | public class Events {
6 | private static abstract class Event {
7 | public String error = "";
8 | public boolean didError() {
9 | return !error.isEmpty();
10 | };
11 | }
12 |
13 | //
14 | // LIST EVENTS
15 | //
16 |
17 | private static abstract class ListEvent extends Event {
18 | public String list;
19 | }
20 |
21 | public final static class FetchedListEvent extends ListEvent {
22 | public FetchedListEvent(String list, String error) {
23 | this.list = list;
24 | this.error = error;
25 | }
26 | }
27 |
28 | private static abstract class ModEvent extends ListEvent {
29 | public String modname;
30 | public String dest;
31 |
32 | ModEvent(String modname, String dest, String list, String error) {
33 | this.modname = modname;
34 | this.dest = dest;
35 | this.list = list;
36 | this.error = error;
37 | }
38 | }
39 |
40 | public final static class ModInstallEvent extends ModEvent {
41 | public ModInstallEvent(String modname, String dest, String list, String error) {
42 | super(modname, dest, list, error);
43 | }
44 | }
45 |
46 | public final static class ModUninstallEvent extends ModEvent {
47 | public ModUninstallEvent(String modname, String dest, String list, String error) {
48 | super(modname, dest, list, error);
49 | }
50 | }
51 |
52 | //
53 | // OTHER EVENTS
54 | //
55 |
56 | public final static class SearchEvent {
57 | public String query;
58 | public SearchEvent(String query) {
59 | this.query = query;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/Game.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.support.annotation.NonNull;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 | import java.util.ArrayList;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | public class Game {
13 | public final String name;
14 | private final File file;
15 |
16 | private final Map lists = new HashMap<>();
17 |
18 | public Game(@NonNull String name, @NonNull File file) {
19 | this.name = name;
20 |
21 | this.file = file;
22 | }
23 |
24 | public String getPath() {
25 | return file.getAbsolutePath();
26 | }
27 |
28 | public ModList getList(String path) {
29 | return lists.get(new File(path).getAbsolutePath());
30 | }
31 |
32 | public Mod getMod(String name, String author) {
33 | for (ModList list : lists.values()) {
34 | Mod mod = list.get(name, author);
35 | if (mod != null) {
36 | return mod;
37 | }
38 | }
39 |
40 | return null;
41 | }
42 |
43 | public boolean isValid() {
44 | return file.isDirectory() && new File(file, "mods").isDirectory();
45 | }
46 |
47 | public boolean isLoaded() {
48 | return new File(file, "games").isDirectory();
49 | }
50 |
51 | public boolean hasWorld() {
52 | return new File(file, "worlds/world").isDirectory();
53 | }
54 |
55 | @SuppressWarnings("ResultOfMethodCallIgnored")
56 | public void forceCreate() {
57 | new File(file, "mods").mkdirs();
58 | new File(file, "worlds").mkdirs();
59 | }
60 |
61 | public List getModPaths() {
62 | List paths = new ArrayList<>();
63 | paths.add(new ModDir(new File(file, "mods").getAbsolutePath(), ModList.ModListType.EMLT_MODS));
64 | paths.add(new ModDir(new File(file, "games/minetest_game/mods").getAbsolutePath(), ModList.ModListType.EMLT_GAME_MODS));
65 | return paths;
66 | }
67 |
68 | public List getAllModLists() {
69 | List ret = new ArrayList<>();
70 | ret.addAll(lists.values());
71 | return ret;
72 | }
73 |
74 | public Map getAllMods() {
75 | Map map = new HashMap<>();
76 |
77 | for (ModList list : lists.values()) {
78 | for (Mod mod : list.mods) {
79 | map.put(mod.name, mod);
80 | }
81 | }
82 |
83 | return map;
84 | }
85 |
86 | public void addList(String path, ModList list) {
87 | lists.put(path, list);
88 | }
89 |
90 | public boolean hasPath(String path) {
91 | String root;
92 | try {
93 | root = file.getCanonicalPath();
94 | } catch (IOException e) {
95 | root = file.getAbsolutePath();
96 | }
97 |
98 | File file2 = new File(path);
99 | try {
100 | path = file2.getCanonicalPath();
101 | } catch (IOException e) {
102 | path = file2.getAbsolutePath();
103 | }
104 |
105 | return path.startsWith(root);
106 | }
107 |
108 | public static boolean isMTGMod(String mod_name) {
109 | String[] mods = {
110 | "beds",
111 | "boats",
112 | "bones",
113 | "bucket",
114 | "carts",
115 | "creative",
116 | "default",
117 | "doors",
118 | "dye",
119 | "farming",
120 | "fire",
121 | "flowers",
122 | "give_initial_stuff",
123 | "killme",
124 | "screwdriver",
125 | "sethome",
126 | "sfinv",
127 | "stairs",
128 | "tnt",
129 | "vessels",
130 | "walls",
131 | "wool",
132 | "xpanes"
133 | };
134 |
135 | for (String mod : mods) {
136 | if (mod.equals(mod_name)) {
137 | return true;
138 | }
139 | }
140 |
141 | return false;
142 | }
143 |
144 | public class ModDir {
145 | public String path;
146 | public ModList.ModListType type;
147 |
148 | ModDir(String absolutePath, ModList.ModListType emltGameMods) {
149 | this.path = absolutePath;
150 | this.type = emltGameMods;
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/MinetestConf.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.support.annotation.Nullable;
5 | import android.util.Log;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.BufferedWriter;
9 | import java.io.File;
10 | import java.io.FileReader;
11 | import java.io.FileWriter;
12 | import java.io.IOException;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | /**
17 | * Reads and writes Minetest style configurations
18 | **/
19 | public class MinetestConf {
20 | private final Map settings = new HashMap<>();
21 |
22 | public boolean read(File file) {
23 | if (!file.isFile()) {
24 | Log.e("Conf", "Configfile is not a file! " + file.getAbsolutePath());
25 | return false;
26 | }
27 | try {
28 | BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
29 | String line;
30 |
31 | while ((line = bufferedReader.readLine()) != null) {
32 | int idx = line.indexOf("=");
33 | if (idx >= 0) {
34 | String key = line.substring(0, idx).trim();
35 | String value = line.substring(idx + 1, line.length()).trim();
36 | settings.put(key, value);
37 | }
38 |
39 | }
40 | bufferedReader.close();
41 | return true;
42 | } catch (IOException e) {
43 | e.printStackTrace();
44 | return false;
45 | }
46 | }
47 |
48 | public boolean save(File file) {
49 | try {
50 | BufferedWriter writer = new BufferedWriter(new FileWriter(file));
51 | for (Map.Entry pair : settings.entrySet()) {
52 | writer.write(pair.getKey() + " = " + pair.getValue() + "\n");
53 | }
54 | writer.close();
55 |
56 | return true;
57 | } catch (IOException e) {
58 | e.printStackTrace();
59 | return false;
60 | }
61 | }
62 |
63 | public static boolean isYes(String v) {
64 | v = v.trim();
65 | return (v.equals("true") || v.equals("1") || v.equals("yes"));
66 | }
67 |
68 | public String get(@NonNull String key) {
69 | return settings.get(key);
70 | }
71 |
72 | public boolean getBool(@NonNull String key) {
73 | String value = get(key);
74 | return (value != null) && isYes(value);
75 | }
76 |
77 | public void set(@NonNull String key, @Nullable String value) {
78 | if (value == null) {
79 | value = "";
80 | }
81 | settings.put(key, value);
82 | }
83 |
84 | public void setBool(@NonNull String key, boolean value) {
85 | set(key, value?"true":"false");
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/MinetestDepends.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.util.Log;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.BufferedWriter;
8 | import java.io.File;
9 | import java.io.FileReader;
10 | import java.io.FileWriter;
11 | import java.io.IOException;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | public class MinetestDepends {
16 | public final List hard = new ArrayList<>();
17 | public final List soft = new ArrayList<>();
18 |
19 | public boolean read(@NonNull File file) {
20 | if (!file.isFile()) {
21 | Log.e("Depends", "depfle is not a file! " + file.getAbsolutePath());
22 | return false;
23 | }
24 |
25 | try {
26 | BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
27 | String line;
28 |
29 | while ((line = bufferedReader.readLine()) != null) {
30 | line = line.trim();
31 | if (!line.isEmpty()) {
32 | if (line.endsWith("?")) {
33 | Log.e("Depends", "Soft: " + line.substring(0, line.length() - 1));
34 | soft.add(line.substring(0, line.length() - 1));
35 | } else {
36 | Log.e("Depends", "Hard: " + line);
37 | hard.add(line);
38 | }
39 | }
40 | }
41 | bufferedReader.close();
42 | return true;
43 | } catch (IOException e) {
44 | e.printStackTrace();
45 | return false;
46 | }
47 | }
48 |
49 | public boolean save(File file) {
50 | try {
51 | BufferedWriter writer = new BufferedWriter(new FileWriter(file));
52 | for (String dep : hard) {
53 | writer.write(dep + "\n");
54 | }
55 | for (String dep : soft) {
56 | writer.write(dep + "?\n");
57 | }
58 | writer.close();
59 |
60 | return true;
61 | } catch (IOException e) {
62 | e.printStackTrace();
63 | return false;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/Mod.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.support.annotation.Nullable;
5 |
6 | import com.rubenwardy.minetestmodmanager.manager.ModManager;
7 |
8 | /**
9 | * Represents a mod, installed or not.
10 | */
11 | public class Mod extends ModSpec {
12 | public enum ModType {
13 | EMT_INVALID,
14 | EMT_MOD,
15 | EMT_MODPACK,
16 | EMT_SUBGAME
17 | }
18 |
19 | @NonNull public final ModType type;
20 |
21 | @Nullable public final String title;
22 | @NonNull public final String desc;
23 |
24 | @NonNull public String link;
25 | @Nullable public String path;
26 | @Nullable public String thumbnail_url;
27 | @Nullable public String screenshot_uri;
28 | @Nullable public String forum_url;
29 | public int verified;
30 | public int size;
31 |
32 | public Mod(@NonNull ModType type, @Nullable String listname, @NonNull String name,
33 | @Nullable String title, @NonNull String desc) {
34 | super(name, "", listname);
35 |
36 | this.type = type;
37 | this.title = title;
38 | this.desc = desc;
39 | this.link = "";
40 | this.path = "";
41 | this.screenshot_uri = "";
42 | this.thumbnail_url = null;
43 | this.verified = 0;
44 | this.size = -1;
45 | }
46 |
47 | public boolean isLocalMod() {
48 | return path != null && !path.equals("");
49 | }
50 |
51 | @NonNull
52 | public String getShortDesc() {
53 | String cleaned_desc = desc.trim().replace("\n", " ");
54 | int len = cleaned_desc.indexOf(".", 20) + 1;
55 | int slen = cleaned_desc.length();
56 | len = Math.min(len, slen);
57 | if (len < 20) {
58 | len = slen;
59 | }
60 |
61 | if (len > 100) {
62 | String short_desc = cleaned_desc.substring(0, 99);
63 | char c = short_desc.charAt(short_desc.length() - 1);
64 | while (!(Character.isDigit(c) || Character.isLetter(c))) {
65 | short_desc = short_desc.substring(0, short_desc.length() - 1);
66 | c = short_desc.charAt(short_desc.length() - 1);
67 | }
68 | return short_desc + "…";
69 | } else {
70 | return cleaned_desc.substring(0, len);
71 | }
72 | }
73 |
74 | @NonNull
75 | public String getShortLink() {
76 | String res = (link == null) ? "" : link.replace("https://", "").replace("http://", "");
77 | if (res.length() > 100) {
78 | res = res.substring(0, 99) + "…";
79 | }
80 | return res;
81 | }
82 |
83 | @NonNull
84 | public String getShortForumLink() {
85 | String res = (forum_url == null) ? "" : forum_url.replace("https://", "").replace("http://", "");
86 | if (res.length() > 100) {
87 | res = res.substring(0, 99) + "…";
88 | }
89 | return res;
90 | }
91 |
92 | @Nullable
93 | public String getDownloadSize() {
94 | if (size > 1000000) {
95 | double size2 = Math.round(size / 100000.0) / 10.0;
96 | return size2 + " MB";
97 | } else if (size > 500) {
98 | double size2 = Math.round(size / 100.0) / 10.0;
99 | return size2 + " KB";
100 | } else if (size > 0) {
101 | return size + " B";
102 | } else {
103 | return null;
104 | }
105 | }
106 |
107 | @Override
108 | @NonNull
109 | public String toString() {
110 | return this.name;
111 | }
112 |
113 | public boolean isEnabled(@NonNull MinetestConf conf) {
114 | if (type == ModType.EMT_MOD) {
115 | return conf.getBool("load_mod_" + name);
116 | } else if (type == ModType.EMT_MODPACK) {
117 | assert (path != null);
118 | ModList sublist = new ModList(ModList.ModListType.EMLT_MODS, "", null, path);
119 | ModManager modman = ModManager.getInstance();
120 | modman.updatePathModList(sublist);
121 | for (Mod submod : sublist.mods) {
122 | if (!submod.isEnabled(conf)) {
123 | return false;
124 | }
125 | }
126 | return true;
127 | } else {
128 | return false;
129 | }
130 | }
131 |
132 | public void setEnabled(@NonNull MinetestConf conf, boolean enable) {
133 | if (type == ModType.EMT_MOD) {
134 | conf.setBool("load_mod_" + name, enable);
135 | } else if (type == ModType.EMT_MODPACK) {
136 | assert (path != null);
137 | ModList sublist = new ModList(ModList.ModListType.EMLT_MODS, "", "", path);
138 | ModManager modman = ModManager.getInstance();
139 | modman.updatePathModList(sublist);
140 | for (Mod submod : sublist.mods) {
141 | submod.setEnabled(conf, enable);
142 | }
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/ModList.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.support.annotation.Nullable;
5 | import android.util.Log;
6 |
7 | import java.io.File;
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * A list of mods. May represent a folder in the file system or
15 | */
16 | public class ModList {
17 | public enum ModListType {
18 | EMLT_ONLINE,
19 | EMLT_MODS,
20 | EMLT_GAME_MODS;
21 |
22 | public boolean isLocal() {
23 | return this == EMLT_MODS || this == EMLT_GAME_MODS;
24 | }
25 | }
26 |
27 | @Nullable public final String game_name;
28 | @NonNull public final String listname;
29 | @Nullable public final String engine_root;
30 | @NonNull public final ModListType type;
31 | public boolean valid;
32 | @NonNull public List mods = new ArrayList<>();
33 |
34 | @NonNull
35 | public Map> mods_map = new HashMap<>();
36 |
37 | public ModList(@NonNull ModListType type, @Nullable String game_name, @Nullable String engine_root,
38 | @NonNull String listname) {
39 | this.type = type;
40 | this.game_name = game_name;
41 | this.engine_root = engine_root;
42 | this.listname = listname;
43 | this.valid = true;
44 | }
45 |
46 | @NonNull
47 | public String getShortname() {
48 | // TODO: make this less hacky
49 | return listname.replace("/storage/emulated/0/", "");
50 | }
51 |
52 | public void add(@NonNull Mod mod) {
53 | mods.add(mod);
54 | if (mods_map.containsKey(mod.name)) {
55 | List tmp = mods_map.get(mod.name);
56 | tmp.add(mod);
57 | } else {
58 | List tmp = new ArrayList<>();
59 | tmp.add(mod);
60 | mods_map.put(mod.name, tmp);
61 | }
62 | }
63 |
64 | @Nullable
65 | public String getWorldsDir() {
66 | if (engine_root == null) {
67 | return null;
68 | } else {
69 | return (new File(engine_root, "worlds")).getAbsolutePath();
70 | }
71 | }
72 |
73 | @Nullable
74 | public Mod get(@Nullable String name, @Nullable String author) {
75 | if (name == null) {
76 | return null;
77 | }
78 | if (author != null) {
79 | author = author.trim();
80 | if (author.equals("")) {
81 | author = null;
82 | }
83 | }
84 |
85 | List res = mods_map.get(name);
86 | if (res != null && res.size() > 0) {
87 | if (author == null) {
88 | if (res.size() > 1) {
89 | Log.e("ModList",
90 | "getModList() called without author, yet there are multiple mods of that name.");
91 | }
92 | return res.get(0);
93 | }
94 | for (Mod mod : res) {
95 | if (mod.author.equals(author)) {
96 | return mod;
97 | }
98 | }
99 | }
100 | return null;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/models/ModSpec.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.models;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.support.annotation.Nullable;
5 |
6 | public class ModSpec {
7 | @NonNull public final String name;
8 | @NonNull public String author;
9 | @Nullable public String listname;
10 |
11 | public ModSpec(@NonNull String name, @NonNull String author, @Nullable String listname) {
12 | this.name = name;
13 | this.author = author;
14 | this.listname = listname;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/presenters/DisclaimerPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.presenters
2 |
3 | import android.content.Context
4 | import android.util.Log
5 | import com.rubenwardy.minetestmodmanager.manager.ModManager
6 | import com.rubenwardy.minetestmodmanager.models.ModSpec
7 |
8 | class DisclaimerPresenter(val view: View) {
9 |
10 | fun onAcceptClicked(context: Context) {
11 | view.setAgreedToDisclaimer()
12 |
13 |
14 | val modspec = view.getModInfo()
15 | if (modspec.listname != null && !modspec.name.isEmpty()) {
16 | val modman = ModManager.getInstance()
17 | val list = modman.getModList(modspec.listname)
18 | if (list != null) {
19 | val mod = list.get(modspec.name, modspec.author)
20 | if (mod != null && !mod.link.isEmpty()) {
21 | modman.installUrlModAsync(context, mod,
22 | mod.link,
23 | modman.installDir)
24 | } else {
25 | Log.e("DAct", "Unable to find an installable mod of that name! " + modspec.name)
26 | }
27 | } else {
28 | Log.e("DAct", "Unable to find a ModList of that id! " + modspec.listname)
29 | }
30 | }
31 |
32 | view.finishActivity()
33 | }
34 |
35 | interface View {
36 | fun setAgreedToDisclaimer()
37 | fun finishActivity()
38 | fun getModInfo() : ModSpec
39 | }
40 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/presenters/ModListPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.presenters
2 |
3 | import android.os.Environment
4 | import android.util.Log
5 | import com.rubenwardy.minetestmodmanager.manager.ModManager
6 | import com.rubenwardy.minetestmodmanager.models.Events
7 | import com.rubenwardy.minetestmodmanager.models.Game
8 | import org.greenrobot.eventbus.Subscribe
9 | import java.io.File
10 |
11 | class ModListPresenter(val view: View) {
12 | fun scanFileSystem() {
13 | val extern = Environment.getExternalStorageDirectory()
14 | if (!extern.exists()) {
15 | view.showNoExternalFSDialog()
16 | return
17 | }
18 |
19 | val minetest = Game("Minetest", File(extern, "Minetest"))
20 | val multicraft = Game("Multicraft", File(extern, "MultiCraft"))
21 |
22 | if (!minetest.isValid && !multicraft.isValid) {
23 | view.getIsMinetestInstalled()
24 |
25 | view.showMinetestNotInstalledDialog()
26 |
27 | minetest.forceCreate()
28 | }
29 |
30 | if (!minetest.isValid && !multicraft.isValid) {
31 | view.showNoGameAvailable()
32 | return
33 | }
34 |
35 | val modman = ModManager.getInstance()
36 | modman.registerGame(minetest)
37 | modman.fetchModListAsync()
38 | }
39 |
40 | fun forceModListRefresh() {
41 | val modman = ModManager.getInstance()
42 | for (list in ModManager.getInstance().allModLists) {
43 | if (list.type.isLocal) {
44 | modman.updateLocalModList(list)
45 | }
46 | }
47 | modman.fetchModListAsync()
48 | }
49 |
50 | @Subscribe
51 | fun onModInstall(e: Events.ModInstallEvent) {
52 | if (e.didError()) {
53 | view.showModInstallErrorDialog(e.modname, e.error);
54 | return
55 | } else {
56 | val modman = ModManager.getInstance()
57 | val uninstalled = modman.getMissingDependsForMod(modman.getModList(e.list)!!.get(e.modname, null)!!)
58 | for (a in uninstalled) {
59 | Log.e("MDAct", "Mod not installed: " + a)
60 | }
61 |
62 | if (!uninstalled.isEmpty()) {
63 | view.showInstallsDependsDialog(uninstalled)
64 | }
65 |
66 | view.showModOnlyIfTwoPane(e.list, e.modname);
67 | view.showInstallMessage(e.modname)
68 | }
69 |
70 | view.updateModListAndRecyclerView(e.list)
71 | }
72 |
73 |
74 | interface View {
75 | fun showNoExternalFSDialog()
76 | fun showMinetestNotInstalledDialog()
77 | fun showNoGameAvailable()
78 | fun getIsMinetestInstalled(): Boolean
79 | fun showModInstallErrorDialog(modname: String, error: String)
80 | fun showInstallsDependsDialog(uninstalled: List)
81 | fun updateModListAndRecyclerView(list: String)
82 | fun showInstallMessage(modname: String)
83 | fun showModOnlyIfTwoPane(list: String, modname: String)
84 | }
85 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/restapi/StoreAPI.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.restapi;
2 |
3 | import android.support.annotation.Nullable;
4 | import android.util.Log;
5 |
6 | import com.rubenwardy.minetestmodmanager.models.Mod;
7 | import com.rubenwardy.minetestmodmanager.models.ModList;
8 |
9 | import java.util.List;
10 |
11 | import okhttp3.ResponseBody;
12 | import retrofit2.Call;
13 | import retrofit2.http.Body;
14 | import retrofit2.http.Field;
15 | import retrofit2.http.FormUrlEncoded;
16 | import retrofit2.http.GET;
17 | import retrofit2.http.POST;
18 |
19 | public interface StoreAPI {
20 | @GET("v2/list")
21 | Call> getModList();
22 |
23 | @FormUrlEncoded
24 | @POST("v1/report")
25 | Call sendReport(@Field("modname") String modname,
26 | @Field("msg") String msg,
27 | @Field("reason") String reason,
28 | @Field("author") String author,
29 | @Field("list") String list,
30 | @Field("link") String link);
31 |
32 | @FormUrlEncoded
33 | @POST("v1/on-download")
34 | Call sendDownloadReport(@Field("modname") String modname,
35 | @Field("link") String link,
36 | @Field("size") int size,
37 | @Field("status") int status,
38 | @Field("author") String author,
39 | @Field("error") String error);
40 |
41 | class MissingModReport {
42 | public List mods;
43 | public String required_by;
44 |
45 | public MissingModReport(List mods, String required_by) {
46 | this.mods = mods;
47 | this.required_by = required_by;
48 | }
49 | }
50 |
51 | @POST("v2/on-missing-dep")
52 | Call sendMissingDependsReport(@Body MissingModReport info);
53 |
54 | class RestMod {
55 | public String author;
56 | public String type;
57 | public String basename;
58 | public String title;
59 | public String description;
60 | public String forum_url;
61 | public String download_link;
62 | public String thumbnail;
63 |
64 | @Nullable
65 | Mod toMod(final String modstore_url) {
66 | String modname = this.basename;
67 | String title = this.title;
68 | String link = this.download_link;
69 |
70 | if (modname == null || title == null || null == link) {
71 | return null;
72 | }
73 |
74 | String author = this.author;
75 | String type_s = this.type;
76 |
77 | String desc = "";
78 | if (this.description != null) {
79 | desc = this.description;
80 | }
81 |
82 | String forum = null;
83 | if (this.forum_url != null) {
84 | forum = this.forum_url;
85 | }
86 |
87 | Mod.ModType type = Mod.ModType.EMT_MOD;
88 | if (type_s != null) {
89 | if (type_s.equals("1")) {
90 | type = Mod.ModType.EMT_MOD;
91 | } else if (type_s.equals("2")) {
92 | type = Mod.ModType.EMT_MODPACK;
93 | }
94 | }
95 |
96 | Mod mod = new Mod(type, modstore_url, modname, title, desc);
97 | mod.link = link;
98 | mod.author = author;
99 | mod.forum_url = forum;
100 | mod.size = 0;
101 | mod.thumbnail_url = thumbnail;
102 | return mod;
103 | }
104 |
105 | public static void addAllToList(ModList list, List mods, String modstore_url) {
106 | for (StoreAPI.RestMod rmod : mods) {
107 | Mod mod = rmod.toMod(modstore_url);
108 | if (mod == null) {
109 | Log.e("RestMod", "Invalid object in list");
110 | } else {
111 | list.add(mod);
112 | }
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/restapi/StoreAPIBuilder.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.restapi;
2 |
3 | import com.google.gson.GsonBuilder;
4 |
5 | import retrofit2.Retrofit;
6 | import retrofit2.converter.gson.GsonConverterFactory;
7 |
8 | public class StoreAPIBuilder {
9 | public static final String API_BASE_URL = "https://minetest-mods.rubenwardy.com/";
10 |
11 | private static Retrofit.Builder createBaseBuilder() {
12 | GsonBuilder gsonBuilder = new GsonBuilder();
13 |
14 | return new Retrofit.Builder()
15 | .baseUrl(API_BASE_URL)
16 | .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()));
17 | }
18 |
19 | public static StoreAPI createService() {
20 | return createBaseBuilder().build().create(StoreAPI.class);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/DisclaimerActivity.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views;
2 |
3 | import android.content.SharedPreferences;
4 | import android.content.res.Resources;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.app.ActionBar;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.os.Bundle;
9 | import android.view.View;
10 | import android.widget.Button;
11 |
12 | import com.rubenwardy.minetestmodmanager.R;
13 | import com.rubenwardy.minetestmodmanager.models.ModSpec;
14 | import com.rubenwardy.minetestmodmanager.presenters.DisclaimerPresenter;
15 |
16 | import org.jetbrains.annotations.NotNull;
17 |
18 | public class DisclaimerActivity extends AppCompatActivity implements DisclaimerPresenter.View {
19 | public static final String PREFS_NAME = "com.rubenwardy.minetestmodmanager.PREFS";
20 |
21 | DisclaimerPresenter presenter = new DisclaimerPresenter(this);
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_disclaimer);
27 |
28 | // Show the Up button in the action bar.
29 | ActionBar actionBar = getSupportActionBar();
30 | if (actionBar != null) {
31 | actionBar.setDisplayHomeAsUpEnabled(true);
32 | Resources res = getResources();
33 | actionBar.setTitle(res.getString(R.string.disclaimer_title));
34 | }
35 |
36 | Button button = (Button) findViewById(R.id.accept);
37 | button.setOnClickListener(new View.OnClickListener() {
38 | @Override
39 | public void onClick(@NonNull View v) {
40 | presenter.onAcceptClicked(getApplicationContext());
41 | }
42 | });
43 | }
44 |
45 | @Override
46 | public void setAgreedToDisclaimer() {
47 | SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
48 | SharedPreferences.Editor editor = settings.edit();
49 | editor.putBoolean("agreed_to_disclaimer", true);
50 | editor.apply();
51 | }
52 |
53 | @Override
54 | public void finishActivity() {
55 | finish();
56 | }
57 |
58 | @NotNull
59 | @Override
60 | public ModSpec getModInfo() {
61 | final String listname = getIntent().getStringExtra(ModDetailFragment.ARG_MOD_LIST);
62 | final String modname = getIntent().getStringExtra(ModDetailFragment.ARG_MOD_NAME);
63 | final String author = getIntent().getStringExtra(ModDetailFragment.ARG_MOD_AUTHOR);
64 | return new ModSpec(modname, author, listname);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/ModInfoDialogFragment.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views;
2 |
3 | import android.app.Dialog;
4 | import android.content.DialogInterface;
5 | import android.content.res.Resources;
6 | import android.os.Bundle;
7 | import android.support.annotation.NonNull;
8 | import android.support.v4.app.DialogFragment;
9 | import android.support.v7.app.AlertDialog;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.widget.TextView;
13 |
14 | import com.rubenwardy.minetestmodmanager.R;
15 | import com.rubenwardy.minetestmodmanager.manager.ModManager;
16 | import com.rubenwardy.minetestmodmanager.models.Mod;
17 | import com.rubenwardy.minetestmodmanager.models.ModList;
18 |
19 | public class ModInfoDialogFragment extends DialogFragment {
20 | private Mod mod;
21 |
22 | @NonNull
23 | @Override
24 | public Dialog onCreateDialog(Bundle savedInstanceState) {
25 | if (savedInstanceState == null) {
26 | if (getArguments().containsKey(ModDetailFragment.ARG_MOD_NAME) &&
27 | getArguments().containsKey(ModDetailFragment.ARG_MOD_LIST)) {
28 | String name = getArguments().getString(ModDetailFragment.ARG_MOD_NAME);
29 | String author = getArguments().getString(ModDetailFragment.ARG_MOD_AUTHOR);
30 | String listname = getArguments().getString(ModDetailFragment.ARG_MOD_LIST);
31 | ModManager modman = ModManager.getInstance();
32 |
33 | ModList list = modman.getModList(listname);
34 | if (list == null) {
35 | Resources res = getResources();
36 | mod = new Mod(Mod.ModType.EMT_INVALID,
37 | "", "invalid",
38 | res.getString(R.string.mod_invalid_modlist_title),
39 | listname + ": " + res.getString(R.string.mod_invalid_modlist_desc));
40 | } else {
41 | mod = list.get(name, author);
42 | if (mod == null) {
43 | Resources res = getResources();
44 | list.valid = false;
45 | mod = new Mod(Mod.ModType.EMT_INVALID,
46 | "", "invalid",
47 | res.getString(R.string.mod_invalid_mod_title),
48 | author + "/" + name + ": " + res.getString(R.string.mod_invalid_mod_desc));
49 | }
50 | }
51 | }
52 | }
53 |
54 |
55 | // Use the Builder class for convenient dialog construction
56 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
57 | LayoutInflater inflater = getActivity().getLayoutInflater();
58 | View rootView = inflater.inflate(R.layout.dialog_mod_information, null);
59 |
60 | setupView(rootView);
61 |
62 | builder.setMessage(R.string.modinfo_title)
63 | .setPositiveButton(R.string.dialog_close, new DialogInterface.OnClickListener() {
64 | public void onClick(DialogInterface dialog, int id) { }
65 | })
66 | .setView(rootView);
67 |
68 | // Create the AlertDialog object and return it
69 | return builder.create();
70 | }
71 |
72 | public void setupView(View rootView) {
73 | Resources res = getResources();
74 |
75 | // Mod name
76 | ((TextView) rootView.findViewById(R.id.mod_detail_name)).setText(mod.name);
77 |
78 | // Type
79 | String type;
80 | if (mod.type == Mod.ModType.EMT_MOD) {
81 | type = res.getString(R.string.modinfo_details_type_mod);
82 | } else if (mod.type == Mod.ModType.EMT_MODPACK) {
83 | type = res.getString(R.string.modinfo_details_type_modpack);
84 | } else if (mod.type == Mod.ModType.EMT_SUBGAME) {
85 | type = res.getString(R.string.modinfo_details_type_subgame);
86 | } else {
87 | type = "Invalid";
88 | }
89 | ((TextView) rootView.findViewById(R.id.mod_detail_type)).setText(type);
90 |
91 | // Location
92 | if (mod.isLocalMod()) {
93 | ((TextView) rootView.findViewById(R.id.mod_detail_location)).setText(mod.path);
94 | } else {
95 | rootView.findViewById(R.id.mod_detail_loc_row).setVisibility(View.GONE);
96 | }
97 |
98 | // Download link and size
99 | if (mod.isLocalMod()) {
100 | rootView.findViewById(R.id.mod_detail_link_row).setVisibility(View.GONE);
101 | rootView.findViewById(R.id.mod_detail_size_row).setVisibility(View.GONE);
102 | } else {
103 | ((TextView) rootView.findViewById(R.id.mod_detail_link)).setText(mod.getShortLink());
104 | String dlsize = mod.getDownloadSize();
105 | if (dlsize == null) {
106 | dlsize = res.getString(R.string.modinfo_details_size_unknown);
107 | }
108 | ((TextView) rootView.findViewById(R.id.mod_detail_size)).setText(dlsize);
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/ReadmeActivity.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views;
2 |
3 | import android.content.res.Resources;
4 | import android.support.v7.app.ActionBar;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.os.Bundle;
7 | import android.view.MenuItem;
8 | import android.widget.TextView;
9 |
10 | import com.rubenwardy.minetestmodmanager.R;
11 | import com.rubenwardy.minetestmodmanager.manager.Utils;
12 |
13 | import java.io.File;
14 |
15 | public class ReadmeActivity extends AppCompatActivity {
16 | public static final String ARG_MOD_PATH = "path";
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_readme);
22 |
23 | ActionBar actionBar = getSupportActionBar();
24 | if (actionBar != null) {
25 | actionBar.setDisplayHomeAsUpEnabled(true);
26 | Resources res = getResources();
27 | actionBar.setTitle(res.getString(R.string.readme_title));
28 | }
29 |
30 | TextView text = (TextView) findViewById(R.id.text);
31 | assert text != null;
32 |
33 | String path = getIntent().getStringExtra(ARG_MOD_PATH);
34 | File folder = new File(path);
35 | if (!folder.isDirectory()) {
36 | text.setText("Unable to find dir " + path);
37 | return;
38 | }
39 |
40 | File readme = Utils.getReadmePath(folder);
41 | if (readme == null) {
42 | text.setText("Unable to find any valid readme files");
43 | } else {
44 | text.setText(Utils.readTextFile(readme));
45 | }
46 |
47 | }
48 |
49 | @Override
50 | public boolean onOptionsItemSelected(MenuItem item) {
51 | switch (item.getItemId()) {
52 | case android.R.id.home:
53 | finish();
54 | return true;
55 | }
56 | return super.onOptionsItemSelected(item);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/ReportActivity.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views;
2 |
3 | import android.content.res.Resources;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.support.design.widget.Snackbar;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.support.v7.widget.Toolbar;
10 | import android.util.Log;
11 | import android.view.Menu;
12 | import android.view.MenuItem;
13 | import android.view.View;
14 | import android.widget.AdapterView;
15 | import android.widget.ArrayAdapter;
16 | import android.widget.Button;
17 | import android.widget.EditText;
18 | import android.widget.Spinner;
19 | import android.widget.TextView;
20 |
21 | import com.rubenwardy.minetestmodmanager.R;
22 | import com.rubenwardy.minetestmodmanager.manager.ModManager;
23 |
24 | public class ReportActivity extends AppCompatActivity {
25 | public static final String EXTRA_LIST = "list";
26 | public static final String EXTRA_MOD_NAME = "modname";
27 | public static final String EXTRA_AUTHOR = "author";
28 | public static final String EXTRA_LINK = "link";
29 | private String selected = "mal";
30 |
31 | private String listname;
32 | private String link;
33 | private String author;
34 | private String modname;
35 |
36 | private @NonNull String str_make_nonnull(@Nullable String str) {
37 | if (str == null) {
38 | return "";
39 | } else {
40 | return str;
41 | }
42 | }
43 |
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_report);
49 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
50 | setSupportActionBar(toolbar);
51 | if (getSupportActionBar() != null) {
52 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
53 | }
54 |
55 | listname = str_make_nonnull(getIntent().getStringExtra(EXTRA_LIST));
56 | link = str_make_nonnull(getIntent().getStringExtra(EXTRA_LINK));
57 | author = str_make_nonnull(getIntent().getStringExtra(EXTRA_AUTHOR));
58 | modname = str_make_nonnull(getIntent().getStringExtra(EXTRA_MOD_NAME));
59 |
60 | Resources res = getResources();
61 |
62 | TextView tv = (TextView) findViewById(R.id.mod_details);
63 | String details = String.format(res.getString(R.string.report_modname_by_authorname), modname, author);
64 | details += "\n" + link;
65 | details += "\n" + listname;
66 | tv.setText(details);
67 |
68 | final Spinner spinner = (Spinner) findViewById(R.id.spinner);
69 | ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
70 | R.array.report_reasons, android.R.layout.simple_spinner_item);
71 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
72 | spinner.setAdapter(adapter);
73 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
74 | @Override
75 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
76 | switch (position) {
77 | case 0:
78 | selected = "mal";
79 | break;
80 | case 1:
81 | selected = "dw";
82 | break;
83 | case 2:
84 | default:
85 | selected = "other";
86 | break;
87 | }
88 |
89 | Log.w("RAct", selected);
90 | }
91 |
92 | @Override
93 | public void onNothingSelected(AdapterView> parent) {
94 |
95 | }
96 | });
97 | }
98 |
99 | @Override
100 | public boolean onCreateOptionsMenu(Menu menu) {
101 | getMenuInflater().inflate(R.menu.menu_report, menu);
102 |
103 | return true;
104 | }
105 |
106 | @Override
107 | public boolean onOptionsItemSelected(MenuItem item) {
108 | switch (item.getItemId()) {
109 | case R.id.send:
110 | EditText textbox = (EditText) findViewById(R.id.editText);
111 | String info = str_make_nonnull(textbox.getText().toString());
112 |
113 | ModManager modman = ModManager.getInstance();
114 | modman.reportModAsync(modname, author, listname, link, selected, info);
115 | finish();
116 | return true;
117 | }
118 |
119 | return false;
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/SettingsAndAboutActivity.kt:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views
2 |
3 | import android.os.Bundle
4 | import android.support.v7.app.AppCompatActivity
5 | import android.view.View
6 | import android.widget.AdapterView
7 | import android.widget.ArrayAdapter
8 | import android.widget.Spinner
9 |
10 | import com.rubenwardy.minetestmodmanager.R
11 | import com.rubenwardy.minetestmodmanager.themeToDayNightMode
12 | import android.content.Intent
13 | import android.app.AlarmManager
14 | import android.app.PendingIntent
15 | import android.content.Context
16 | import android.net.Uri
17 | import android.util.Log
18 | import android.widget.Switch
19 |
20 |
21 | class SettingsAndAboutActivity : AppCompatActivity() {
22 |
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | setContentView(R.layout.activity_settingsandabout)
26 |
27 | if (supportActionBar != null) {
28 | supportActionBar!!.setDisplayHomeAsUpEnabled(true)
29 | }
30 |
31 | val settings = getSharedPreferences(DisclaimerActivity.PREFS_NAME, 0)
32 |
33 | val previewScreens = findViewById(R.id.settings_screenshot_previews) as Switch
34 | previewScreens.isChecked = settings.getBoolean("showScreenshotPreviews", true)
35 | previewScreens.setOnCheckedChangeListener { _, isChecked ->
36 | val editor = getSharedPreferences(DisclaimerActivity.PREFS_NAME, 0).edit()
37 | editor.putBoolean("showScreenshotPreviews", isChecked)
38 | editor.apply()
39 | }
40 |
41 | val spinner = findViewById(R.id.settings_theme)
42 | val adapter = ArrayAdapter.createFromResource(this, R.array.settings_theme_options, android.R.layout.simple_spinner_item)
43 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
44 | spinner.adapter = adapter
45 | spinner.setSelection(settings.getInt("theme", 0))
46 | spinner.onItemSelectedListener = object: AdapterView.OnItemSelectedListener {
47 | override fun onNothingSelected(parent: AdapterView<*>?) {}
48 |
49 | override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
50 | val editor = getSharedPreferences(DisclaimerActivity.PREFS_NAME, 0).edit()
51 | editor.putInt("theme", position)
52 | editor.apply()
53 |
54 | delegate.setLocalNightMode(themeToDayNightMode(position))
55 | }
56 | }
57 |
58 | findViewById(R.id.settings_restart).setOnClickListener {
59 | // This is quite hacky, however it seems to be the only way to reliably do this
60 |
61 | Log.e("SettingsAndAbout", "Restarting app")
62 |
63 | val mStartActivity = Intent(this, SettingsAndAboutActivity::class.java)
64 | val mPendingIntentId = 123456
65 | val mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity,
66 | PendingIntent.FLAG_CANCEL_CURRENT)
67 | val mgr = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager
68 | mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent)
69 | System.exit(0)
70 | }
71 |
72 | findViewById(R.id.source).setOnClickListener {
73 | val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/rubenwardy/mtmods4android/"))
74 | startActivity(browserIntent)
75 | }
76 |
77 | findViewById(R.id.translate).setOnClickListener {
78 | val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://hosted.weblate.org/projects/minetest/mtmods4android/"))
79 | startActivity(browserIntent)
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/SplashActivity.kt:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views
2 |
3 | import android.Manifest
4 | import android.annotation.SuppressLint
5 | import android.content.pm.PackageManager
6 | import android.support.v7.app.AppCompatActivity
7 | import android.os.Bundle
8 | import android.support.v4.app.ActivityCompat
9 | import android.support.v4.content.ContextCompat
10 | import android.content.Intent
11 | import android.widget.Toast
12 | import com.rubenwardy.minetestmodmanager.R
13 |
14 |
15 | class SplashActivity : AppCompatActivity() {
16 |
17 | private val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: Int = 122
18 |
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | checkPermission()
23 | }
24 |
25 | private fun permissionsOK() {
26 | val intent = Intent(this, ModListActivity::class.java)
27 | startActivity(intent)
28 | finish()
29 | }
30 |
31 | private fun permissionsDenied() {
32 | Toast.makeText(this, R.string.perm_storage_needed, Toast.LENGTH_SHORT).show()
33 | finish()
34 | }
35 |
36 | private fun checkPermission() {
37 | if (ContextCompat.checkSelfPermission(this,
38 | Manifest.permission.WRITE_EXTERNAL_STORAGE)
39 | != PackageManager.PERMISSION_GRANTED) {
40 | if (ActivityCompat.shouldShowRequestPermissionRationale(this,
41 | Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
42 | permissionsDenied()
43 | } else {
44 | ActivityCompat.requestPermissions(this,
45 | arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
46 | PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE)
47 | }
48 | } else {
49 | permissionsOK()
50 | }
51 | }
52 |
53 | override fun onRequestPermissionsResult(requestCode: Int,
54 | permissions: Array, grantResults: IntArray) {
55 | when (requestCode) {
56 | PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE -> {
57 | // If request is cancelled, the result arrays are empty.
58 | if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
59 | permissionsOK()
60 | } else {
61 | permissionsDenied()
62 | }
63 | return
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rubenwardy/minetestmodmanager/views/WorldConfigActivity.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager.views;
2 |
3 | import android.content.DialogInterface;
4 | import android.content.res.Resources;
5 | import android.os.Environment;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.design.widget.Snackbar;
9 | import android.support.v7.app.ActionBar;
10 | import android.support.v7.app.AlertDialog;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.os.Bundle;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.support.v7.widget.Toolbar;
15 | import android.view.LayoutInflater;
16 | import android.view.Menu;
17 | import android.view.MenuItem;
18 | import android.view.View;
19 | import android.view.ViewGroup;
20 | import android.widget.CheckBox;
21 | import android.widget.CompoundButton;
22 |
23 | import com.rubenwardy.minetestmodmanager.R;
24 | import com.rubenwardy.minetestmodmanager.models.MinetestConf;
25 | import com.rubenwardy.minetestmodmanager.models.Mod;
26 | import com.rubenwardy.minetestmodmanager.models.ModList;
27 | import com.rubenwardy.minetestmodmanager.manager.ModManager;
28 |
29 | import java.io.File;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | public class WorldConfigActivity extends AppCompatActivity {
34 | @Nullable
35 | private String modpath = null;
36 | @Nullable
37 | private MinetestConf conf = null;
38 | @Nullable
39 | private File conf_file = null;
40 |
41 | @Override
42 | protected void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_world_config);
45 |
46 | File extern = Environment.getExternalStorageDirectory();
47 | File mt_root = new File(extern, "/Minetest");
48 | File mt_dir = new File(mt_root, "/mods");
49 | modpath = mt_dir.getAbsolutePath();
50 |
51 | conf = new MinetestConf();
52 | File world_dir = new File(mt_root, "/worlds/singleplayerworld");
53 | conf_file = new File(world_dir, "/world.mt");
54 | if (!world_dir.isDirectory()) {
55 | if (!world_dir.mkdirs()) {
56 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
57 | alertDialogBuilder.setTitle(R.string.dialog_nowld_title);
58 | alertDialogBuilder.setCancelable(false);
59 | alertDialogBuilder.setMessage(R.string.dialog_nowld_msg);
60 | alertDialogBuilder.setNegativeButton(R.string.dialog_close, new DialogInterface.OnClickListener() {
61 | public void onClick(DialogInterface dialog, int id) {
62 | WorldConfigActivity.this.finish();
63 | }
64 | });
65 | AlertDialog alertDialog = alertDialogBuilder.create();
66 | alertDialog.show();
67 | return;
68 | }
69 | }
70 | if (!conf.read(conf_file)) {
71 | // Create configuration file
72 | conf.set("gameid", "minetest");
73 | conf.set("backend", "sqlite3");
74 | }
75 |
76 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
77 | setSupportActionBar(toolbar);
78 | toolbar.setTitle(getTitle());
79 |
80 | // Show the Up button in the action bar.
81 | ActionBar actionBar = getSupportActionBar();
82 | if (actionBar != null) {
83 | actionBar.setDisplayHomeAsUpEnabled(true);
84 | Resources res = getResources();
85 | actionBar.setTitle(res.getString(R.string.world_config));
86 | }
87 |
88 | View recyclerView = findViewById(R.id.mod_list);
89 | assert recyclerView != null;
90 | setupRecyclerView((RecyclerView) recyclerView);
91 | }
92 |
93 | @Override
94 | public boolean onCreateOptionsMenu(Menu menu) {
95 | getMenuInflater().inflate(R.menu.menu_world_config, menu);
96 |
97 | return true;
98 | }
99 |
100 | @Override
101 | public boolean onOptionsItemSelected(MenuItem item) {
102 | if (conf == null) {
103 | return false;
104 | }
105 |
106 | switch (item.getItemId()) {
107 | case R.id.accept:
108 | conf.save(conf_file);
109 | Resources res = getResources();
110 | String text = res.getString(R.string.world_config_saved);
111 | Snackbar.make(findViewById(R.id.mod_list), text, Snackbar.LENGTH_LONG)
112 | .setAction("Action", null).show();
113 | return true;
114 | }
115 |
116 | return false;
117 | }
118 |
119 | private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
120 | //Add your adapter to the sectionAdapter
121 | ModListRecyclerViewAdapter adapter = new ModListRecyclerViewAdapter();
122 | recyclerView.setAdapter(adapter);
123 |
124 | ModManager modman = ModManager.getInstance();
125 | ModList list = modman.getModList(modpath);
126 | if (list == null) {
127 | finish();
128 | return;
129 | }
130 | List mods = new ArrayList<>(list.mods);
131 | adapter.setMods(mods);
132 |
133 | }
134 |
135 | public class ModListRecyclerViewAdapter
136 | extends RecyclerView.Adapter {
137 |
138 | private List mods;
139 |
140 | public ModListRecyclerViewAdapter() {
141 | mods = new ArrayList<>();
142 | }
143 |
144 | public void setMods(List mods) {
145 | this.mods = mods;
146 | }
147 |
148 | @NonNull
149 | @Override
150 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
151 | View view = LayoutInflater.from(parent.getContext())
152 | .inflate(R.layout.mod_checklist_content, parent, false);
153 | return new ViewHolder(view);
154 | }
155 |
156 | @Override
157 | public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
158 | // Get Mod
159 | holder.mod = mods.get(position);
160 |
161 | //
162 | // Fill out TextViews
163 | //
164 |
165 | holder.view_modname.setText(holder.mod.name);
166 |
167 | //
168 | // Register callback
169 | //
170 | assert conf != null;
171 | boolean enabled = holder.mod.isEnabled(conf);
172 | if (holder.mod.type == Mod.ModType.EMT_MODPACK) {
173 | holder.view_modname.setText(holder.mod.name + " (Modpack)");
174 | }
175 | holder.view_modname.setChecked(enabled);
176 |
177 | holder.view_modname.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
178 | @Override
179 | public void onCheckedChanged(CompoundButton comp_btn, boolean checked) {
180 | holder.mod.setEnabled(conf, checked);
181 | }
182 | });
183 | }
184 |
185 | @Override
186 | public int getItemCount() {
187 | return mods.size();
188 | }
189 |
190 | public class ViewHolder extends RecyclerView.ViewHolder {
191 | @NonNull
192 | public final View view;
193 | @NonNull
194 | public final CheckBox view_modname;
195 | @Nullable
196 | public Mod mod;
197 |
198 | public ViewHolder(@NonNull View view) {
199 | super(view);
200 | this.view = view;
201 | view_modname = (CheckBox) view.findViewById(R.id.modname);
202 | }
203 |
204 | @NonNull
205 | @Override
206 | public String toString() {
207 | return super.toString() + " '" + view_modname.getText() + "'";
208 | }
209 | }
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi-v11/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-hdpi-v11/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi-v9/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-hdpi-v9/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-hdpi/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi-v11/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-mdpi-v11/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi-v9/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-mdpi-v9/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-mdpi/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v11/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-xhdpi-v11/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi-v9/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-xhdpi-v9/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-xhdpi/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v11/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-xxhdpi-v11/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi-v9/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-xxhdpi-v9/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/drawable-xxhdpi/notification_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | -
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_check_depends_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_find_elsewhere_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_forum_topic_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_info_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_mods_by_author.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_readme_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mod_action_report_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_public_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/mod_preview_circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_disclaimer.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
21 |
25 |
26 |
30 |
31 |
41 |
45 |
46 |
56 |
60 |
61 |
71 |
75 |
76 |
90 |
91 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_mod_detail.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
16 |
17 |
25 |
26 |
32 |
33 |
34 |
35 |
36 |
37 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_mod_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_readme.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
17 |
18 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_report.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
22 |
23 |
24 |
25 |
35 |
39 |
43 |
44 |
54 |
55 |
59 |
60 |
70 |
71 |
75 |
76 |
86 |
87 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settingsandabout.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
21 |
22 |
26 |
27 |
38 |
39 |
44 |
45 |
50 |
51 |
58 |
59 |
64 |
65 |
66 |
67 |
73 |
74 |
80 |
81 |
93 |
97 |
102 |
107 |
112 |
117 |
122 |
123 |
128 |
129 |
134 |
135 |
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_world_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
21 |
22 |
23 |
24 |
29 |
30 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/depends_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_mod_information.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
16 |
20 |
21 |
22 |
23 |
27 |
31 |
32 |
33 |
34 |
38 |
42 |
43 |
44 |
45 |
49 |
53 |
54 |
55 |
56 |
60 |
64 |
65 |
66 |
76 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_install_depends_dialog.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/mod_checklist_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/mod_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
32 |
33 |
48 |
49 |
58 |
59 |
60 |
68 |
69 |
84 |
85 |
93 |
94 |
95 |
99 |
100 |
104 |
105 |
116 |
117 |
118 |
119 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/mod_list_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
24 |
25 |
33 |
34 |
43 |
44 |
54 |
55 |
65 |
66 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/mod_list_twopane.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
20 |
21 |
28 |
29 |
44 |
45 |
60 |
61 |
70 |
71 |
72 |
80 |
81 |
96 |
97 |
105 |
106 |
107 |
111 |
112 |
116 |
117 |
128 |
129 |
130 |
131 |
137 |
138 |
139 |
140 |
141 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/section.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
25 |
26 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_mod_list.xml:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_report.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_world_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-cs/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Minetest Mody
3 |
4 |
5 | Externí úložiště není dostupné
6 | Nemohu nalézt adresář Minetestu! Je potřeba externí úložiště (ne nutně SD karta), kam bude mít aplikace přístup.
7 | Selhalo vytvoření složky s mody Minetestu
8 | Předtím na tomto zařízení neexistoval adresář s mody a jeho vytvoření selhalo. Možná systém blokuje přístup aplikace ke složce Minetestu. Zkuste jej spustit.
9 | Zavřít
10 | Nemohu vytvořit svět
11 | Minetest není nainstalovaný
12 | Instaluji %1$s…
13 | O této aplikaci
14 | Tvůrci
15 | Vyvinuto uživatelem rubenwardy (rubenwardy.com)
16 | Najít jinde
17 | Přijmout a nainstalovat
18 |
19 |
20 | Co můžete dělat?
21 | Není to obchod s mody, pouze jejich vyhledávač
22 | Bez záruky
23 | Zřeknutí se odpovědnosti
24 | Uložené nastavení
25 |
26 |
27 | Přijmout
28 | Nastavení světa
29 | Detaily
30 | Důvod
31 | Volitelné vysvětlení
32 | %1$s od %2$s
33 | Nahlásit mod
34 | Readme
35 |
36 |
37 | Balíček modů
38 | Neznámý
39 | Velikost ke stažení
40 | Stahovací URL
41 | Složka
42 | Typ
43 | Autor
44 | Název modu
45 | Informace
46 | Zobrazit Readme
47 |
48 | Zobrazit stránku na fóru
49 | Nahlásit mod
50 | Zobrazit informace
51 | Zobrazit
52 |
53 | Odinstalovat
54 |
55 | Instalovat
56 | Podrobnosti o modu
57 | Nainstalovat potřebné mody
58 | Rozbaluji…
59 | Stahuji…
60 | Připojuji…
61 | %1$s nainstalován.
62 | Instaluji mod…
63 | Ne
64 | Ano, ohodnotit
65 | Dostupné mody
66 | Nainstalováno %1$s modů
67 | Hledat
68 |
69 |
70 | Vše v pořádku!
71 | Pokus o vytvoření světa ke konfiguraci selhal.
72 | Před používáním této aplikace doporučujeme nejprve nainstalovat Minetest!
73 | Všechny závislosti byly nainstalovány.
74 |
75 | Mod zapnete kliknutím na ikonu světa.
76 |
77 |
78 | Instalace modu %1$s selhala. Chyba: %2$s.
79 | Odinstalace modu %1$s selhala. Chyba: %2$s.
80 | Ahoj! Nedali byste nám pár hvězdiček?
81 | Nemohu zjistit původ tohoto modu.
82 |
83 | Tento mod nepochází od známého autora.
84 | Tento mod pochází od známého autora.
85 | Zkontrolovat chybějící závislosti
86 | Mod už byl nainstalován do %1$s
87 | Děkujeme uživateli Krock (alias SmallJoker) za napsání vyhledávače Krock\'s Mod Search, na němž je založeno vyhledávání v této aplikaci.
88 | Děkujeme uživateli DonBatman za zpětnou vazbu při vývoji
89 | Logo aplikace je založeno na logu Minetestu, které bylo vytvořeno uživatelem erlehmann pod licencí CC-BY-SA 3.0
90 | Aplikace též využívá mnoho standardních ikon Androidu pod licencí CC-BY 4.0
91 | Děkujeme následujícím překladatelům: Soph (francouzština), Dragonop (španělština), Adrian (němčina), monolifed (turečtina), a muhdnurhidayat (malajština).
92 | Stažení seznamu dostupných modů selhalo. Chyba: %1$s.
93 |
94 | Chtěli byste nainstalovat chybějící závislosti?
95 | Bohužel se nepodařilo najít všechny potřebné mody :(
96 | Bohužel se nepodařilo najít žádné potřebné mody :(
97 | Neplatný mod
98 | Nelze tento mod nalézt. Nebyl smazán?
99 | Neplatná umístění/cesta k modu
100 | Nelze nalézt takové umístění. Nebyla příslušná složka smazána nebo není seznam dostupných modů offline?
101 |
102 |
103 | VAROVÁNÍ: Ujistěte se, že jste alespoň jednou spustili Minetest, některé mody by měly být součástí výchozí instalace.
104 |
105 | Vyberte prosím důvod nahlášení modu. Pokud máte jakékoli další informace, vyplňte je prosím do textového pole.
106 | Používáním této služby souhlasíte s následujícími pravidly a podmínkami.
107 | Pokud si nejste jistí bezpečností modu, podívejte se do diskuzního vlákna modu. Zkontrolujte stáří modu a co na něj říkají další uživatelé.
108 |
109 | Zde uvedené mody jsou vybrány z Minetest Fóra. Soubory se stahují z odkazu, který uvedl autor modu ve svém příspěvku, a proto nemůžeme zaručit bezpečnost modů. Autoři aplikace mody ani nijak nekontrolují.
110 |
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Minetest Mods
4 | Crédits
5 | Développé par rubenwardy
6 | Gratitude à DonBatman pour le feedback pendant le développement.
7 | Cette appli utilise aussi des icônes standardes d\'Android, que sont CC-BY 4.0
8 | Gratitude à Krock (allas Smalljoker) pour avoir créé Krock\'s Mod Search, le crawler de laquelle la liste de mods disponible est dérivée.
9 | Le logo d\'appli est basé sur le logo de Minetest, CC-BY-SA 3.0, et créé par erlehmann
10 | Accepter
11 | Accepter et installer
12 | Installer
13 | Rapporter
14 | Chercher
15 | Désinstaller
16 | Nom de mod
17 | Connecte…
18 | Auteur
19 | Thème de forum
20 | Télécharger l\'URL
21 | Dossier
22 | Mesure du téléchargement
23 | Type
24 | Fermer
25 | On ne peuvait pas.
26 | Lire
27 | Détail du mod
28 | Inconnu
29 | Non
30 | Détails
31 | Mods disponibles
32 | Evaluer
33 | Arrache…
34 | Télécharge…
35 | Raison
36 | Message optionnel
37 | S\'il vous plaît selectionner la raison de laquelle on rapporte cet mod. Si on a plus d\'information, l\'écrit dans la zone de texte s\'il vous plaît.
38 | Rapporter un mod
39 | Limitation de responsabilité
40 | Pack de mods
41 | Configuration de monde
42 | Configuration enregistrée
43 | Mod non valide
44 | Mod en installation
45 | Voir plus d\'information
46 | Veut-on nous évaluer ?
47 | Que peut-on faire ?
48 | Aucune garantie
49 | Aucun stockage disponible
50 | Endroit ou chemin de mod non valide
51 | Installé %1$s.
52 | Echoué à installer le mod %1$s. Erreur: %2$s.
53 | Echouer à désinstaller le mod %1$s. Erreur: %2$s.
54 | Activer un mod en cliquant l\'icône de monde.
55 | %1$s en installation
56 | On n\'a pas pu trouver cet mod. Il a été supprimé ?
57 | Echoué à créér un dossier de mods
58 | Pas un Stockage de Mods, mais un Découvreur de Mods
59 | Incapable de créér un monde
60 | Nous avons essayé de créér un monde pour vous à configurer, mais l\'opération à ėchoué.
61 | En utilisant cet service, on accepte aux termes et conditions suivants.
62 | Mods de %1$s installés
63 | Trouver ailleurs
64 | Merci aux traducteurs: Soph (français), Dragonpop (Espangnol), Adrian (allemand), monolifed (turc), et muhdnurhidayat (malais).
65 | Il n\'avait pas un dossier Minetest sur cet appareil, donc on essayé à crer un nouveau. Mais ça n\'a pas functionné. Peut-être était l\'access bloque par votre appareil.S\'il vous plaît essayer à ouvrir Minetest.
66 | "Les mods nommé ici sont disponible sur les forums de Minetest. Ils sont télécharger par l'application directement du lien nommé par l'auteur. Et donc c'est impossible de vérifier touts les mods. Si vous êtes pas sûre de la sécurité d'un mod on vous prie de chercher les forums pour cet mod et liser les commentaires d'autres utilisateurs."
67 | Téléchargement de la mod list échouché. Erreur: %1$s. Plus d\'Information.
68 | On n\'a pas reussi à trouver le lieu de cette mod. Était le dossier déjà effacé, ou la liste de mods est hors connexion ?
69 | Cette Mod est déjà installé sur: %1$s
70 | Afficher
71 | "Cette mod n'était pas cré par un auteur connu. On est incapable de trouver la source."
72 | Cette mod était cré par un auteur connu.
73 | Information
74 | %1$s de %2$s
75 |
76 |
--------------------------------------------------------------------------------
/app/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Minetest Mods
3 |
4 |
5 | Chiudi
6 | Impossibile creare il mondo
7 | Minetest non è installato
8 | È raccomandato che installi Minetest prima di utilizzare questa applicazione dal tuo app store!
9 | Tutto bene!
10 | Tutte le dipendenze richieste sono installate.
11 |
12 | Cerca
13 |
14 |
15 | Mod disponibili
16 | Valutare
17 | No
18 | Abilita una mod cliccando sull\'icona del mondo.
19 |
20 |
21 | Installazione della mod…
22 | Installata %1$s.
23 | In connessione…
24 | In download…
25 | Fallita la disinstallazione della mod %1$s. Errore: %2$s.
26 | Vuoi installare queste dipendenze mancanti?
27 | Purtroppo non siamo riusciti a trovare tutte le mod richieste :(
28 | Purtroppo non siamo riusciti a trovare nessuna delle mod richieste :(
29 | Dettagli della mod
30 | Installa
31 | Disinstalla
32 |
33 | Mod già installata su %1$s
34 | Vedi informazioni
35 | Controlla le dipendenze mancanti
36 | Questa mod è stata creata da un autore conosciuto.
37 | Questa mod non è stata creata da un autore conosciuto.
38 | Impossibile determinare la fonte di questa mod.
39 |
40 | Mod non valida
41 | Non siamo riusciti a trovare questa mod. È stata cancellata?
42 | Informazioni
43 | Nome della mod
44 | Autore
45 | Tipo
46 | Cartella
47 | Sconosciuto
48 | Per favore seleziona la ragione per cui stai riportando questa mod. Se hai altre informazioni, per favore scrivile nella casella di testo.
49 | Ragione
50 | Messaggio opzionale
51 | Dettagli
52 | Accetta
53 | Configurazione salvata
54 |
55 |
56 | Usando questo servizio accetti i seguenti termini e condizioni.
57 | Nessuna garanzia
58 | Cosa puoi fare?
59 | Se non sei sicuro riguardo la sicurezza di una mod guarda il suo topic sul forum. Controlla quanto è vecchio il post e cosa i commenti dicono.
60 |
61 | Accetta e installa
62 |
63 |
64 | Riguardo questa applicazione
65 | Crediti
66 | Sviluppato da rubenwardy (rubenwardy.com)
67 | Trova altrove
68 | Grazie ai seguenti traduttori: il mio amico Soph (Francese), Dragonop (Spagnolo), Adrian (Tedesco), monolifed (Turco) e muhdnurhidayat (Malese).
69 | Abbiamo cercato di creare un mondo per te da configurare, ma l\'operazione ha fallito.
70 | Installando %1$s…
71 | Estraendo…
72 | Installa le mod richieste
73 | Riporta mod
74 | Dimensione del download
75 | Leggimi
76 |
77 |
78 | Riporta Mod
79 | %1$s di %2$s
80 | Configurazione del mondo
81 |
82 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ms/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Mods Minetest
3 |
4 |
5 | Tiada simpanan luaran
6 | Kami tidak jumpa folder Minetest kerana tiada simpanan luaran. Simpanan luaran adalah lokasi fail berkongsi pada peranti anda, dan tidak semestinya bermaksud kad SD.
7 | Gagal mencipta folder mods Minetest
8 | Tidak ada folder untuk mods pada peranti anda, jadi kami cuba untuk menciptanya. Namun begitu, percubaan tersebut gagal. Mungkin sistem tidak membenarkan app ini mengaksesnya. Cuba jalankan Minetest.
9 | Tutup
10 | Gagal mencipta dunia
11 | Kami cuba untuk mencipta dunia agar anda boleh menata rajah namun operasi tersebut gagal.
12 | Minetest belum dipasang
13 | Adalah disarankan agar anda pasang Minetest sebelum menggunakan app ini daripada kedai app anda!
14 | Semuanya OK!
15 | Kesemua kebergantungan yang diperlukan telah dipasang.
16 |
17 | Cari
18 |
19 |
20 | Mods yang tersedia
21 | Hai! Nak bagi bintang dekat kami tak?
22 | Berikan nilai
23 | Tidak mahu
24 | Bolehkan sebuah mods dengan menekan ikon dunia.
25 |
26 |
27 | Memasang mods…
28 | Selesai pasang %1$s.
29 | Memasang %1$s…
30 | Menyambung…
31 | Memuat turun…
32 | Mengekstrak…
33 | Gagal memasang mods %1$s. Ralat: %2$s.
34 | Gagal menyahpasang mods %1$s. Ralat: %2$s.
35 | Gagal memuat turun senarai mods sedia ada. Ralat: %1$s.
36 |
37 | Pasang mods yang diperlukan
38 | Adakah anda ingin memasang kebergantungan yang hilang ini?
39 | Harap maaf, kami tidak dapat mencari kesemua mods yang diperlukan :(
40 | Harap maaf, ada sesetengah mods yang diperlukan tidak dapat dicari :(
41 | AMARAN: Pastikan anda pernah membuka Minetest sekurang-kurangnya sekali kerana sesetengah daripada mods ini patut datang bersama-sama Minetest.
42 |
43 | Maklumat mods
44 | Pasang
45 | Nyahpasang
46 |
47 | Mods telah dipasangkan dekat %1$s
48 | Lihat
49 |
50 | Lihat Maklumat
51 | Periksa kebergantungan yang hilang
52 | Laporkan mods
53 | Lihat topik forum
54 | Lihat fail Read Me
55 |
56 | Mods ini datang daripada pencipta terkenal.
57 | Mods ini bukannya dibuat oleh pencipta terkenal.
58 | Tidak dapat menentukan sumber mods ini.
59 |
60 | Mods tidak sah
61 | Kami tidak jumpa mods tersebut. Adakah ianya telah dibuang?
62 | Lokasi atau laluan mods tidak sah
63 | Kami tidak jumpa lokasi mods tersebut. Adakah foldernya telah dibuang, atau senarai mods tersedia tidak dikemaskini?
64 |
65 |
66 | Maklumat lanjut
67 | Nama mods
68 | Pencipta
69 | Jenis
70 | Folder
71 | URL muat turun
72 | Saiz muat turun
73 | Tidak diketahui
74 | Pek mods
75 | Baca saya
76 |
77 |
78 | Laporkan mods
79 | %1$s dicipta oleh %2$s
80 | Sila pilih alasan berkaitan tujuan anda melaporkan mods ini. Jika anda mempunyai maklumat lain, sila masukkan ke dalam kotak tulisan yang disediakan.
81 | Alasan
82 | Mesej (jika ingin disertakan)
83 | Maklumat laporan
84 | Konfigurasi dunia
85 | Terima
86 | Konfigurasi telah disimpan
87 |
88 |
89 | Penafian
90 | Dengan menggunakan perkhidmatan ini, anda bersetuju dengan terma dan syarat berikut.
91 | Tiada jaminan
92 | Bukannya kedai mods, tetapi pencari mods
93 | Mods yang disenaraikan adalah sebahagian daripada mods yang dijumpai dekat forum Minetest. Apabila anda memuat turun mods tersebut, anda bukannya memuat turun daripada pelayan kami tetapi ianya dimuat turun daripada pautan yang pencipta asal telah tulis dalam topik forum mereka. Oleh itu, kami tidak menjamin semua mods ini selamat. Tiada manusia yang memeriksa mods yang tersenarai.
94 |
95 | Apa anda boleh lakukan?
96 | Jika anda tidak yakin dengan keselematan sesebuah mods, periksa topik forumnya. Lihat pada usia aliran topik, dan apa yang pengguna balas dalam topik tersebut.
97 |
98 | Terima dan pasang
99 |
100 |
101 | Tentang app ini
102 | Penghargaan
103 | Dibangunkan oleh rubenwardy (rubenwardy.com)
104 | Terima kasih Krock (juga dikenali sebagai SmallJoker) kerana mencipta Pencarian Mods Krock (Krock\'s Mod Search), iaitu pengampu yang app ini gunakan untuk menyenaraikan senarai mods tersedia.
105 | Terima kasih kepada DonBatman untuk maklum balas sewaktu pembangunan app
106 | Logo app ini dicipta oleh erlehmann, dan ianya dicipta berdasarkan logo Minetest yang dilesenkan di bawah CC-BY-SA 3.0
107 | App ini juga menggunakan beberapa ikon Android piawai, dilesenkan di bawah CC-BY 4.0
108 | Cari di tempat lain
109 | Telah pasang %1$s mods
110 | Terima kasih kepada penterjemah berikut: rakan saya Soph (Bahasa Perancis), Dragonop (Bahasa Sepanyol), Adrian (Bahasa Jerman), monolifed (Bahasa Turki), dan muhdnurhidayat (Bahasa Melayu).
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #424242
4 | #2d2d2d
5 | @color/hintText
6 | #212121
7 | #323232
8 | @color/colorPrimary
9 | @color/colorPrimary
10 | #ccc
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Mody minetest\'a
3 |
4 |
5 | Nie dostępna pamięć zewnętrzna
6 | Nie można znaleźć folderu Minetest, ponieważ zewnętrzna pamięć nie jest dostępna. Zewnętrzna pamięć jest współdzieloną przestrzenią na twoim urządzeniu, i nie koniecznie oznacza kartę SD.
7 | Nie udało się utworzyć folderu modów Minetest
8 | Nie znaleziono folderu modów na twoim urządzeniu, więc podjęto próbę jego utworzenia. Jednakże, próba ta nie powiodła się. System może odmawiać dostępu tej aplikacji do niego. Spróbuj uruchomić Minetesta.
9 | Zamknij
10 | Nie udało się utworzyć świata
11 | Podjęto próbę utworzenia świata do skonfigurowania, ale operacja nie powiodła się.
12 | Minetest nie jest zainstalowany
13 | Zaleca się, aby zainstalować Minetest przed użyciem tej aplikacji z app store!
14 | Wszystko dobrze!
15 | Wszystkie wymagane zależności są zainstalowane.
16 |
17 | Szukaj
18 |
19 |
20 | Dostępne mody
21 | Zainstalowano %1$s modów
22 | Hej! Chciałbyś dać nam trochę gwiazdek?
23 | Oceń
24 | Nie
25 | Włącz mod przez kliknięcie w ikonę.
26 |
27 |
28 | Instalowanie modyfikacji…
29 | Zainstalowano %1$s.
30 | Instalowanie %1$s…
31 | Pobieranie…
32 | Wypakowywanie…
33 | Łączenie…
34 | Nie udało się zainstalować moda %1$s. Błąd: %2$s.
35 | Nie udało się pobrać listy dostępnych modów. Błąd: %1$s.
36 |
37 | Instalowanie wymaganych modów
38 | Czy chciałbyś zainstalować brakujące zależności?
39 | Niestety, nie udało się znaleźć wszystkich wymaganych modów :(
40 | Niestety, nie mogliśmy znaleźć jakiegokolwiek z wymaganych modów :(
41 | UWAGA: Upewnij się że uruchomiłeś Minetesta przynajmniej raz, niektóre z tych modów mogą przyjść w paczkach.
42 |
43 | Szczegóły modu
44 | Odinstaluj
45 |
46 | Ten mod jest od dobrze znanego autora.
47 | Ten mod nie został zrobiony przez dobrze znanego autora.
48 | Nie można ustalić źródła tego moda.
49 |
50 | Nieprawidłowy mod
51 | Nie mogliśmy znaleźć tego moda. Czy został usunięty?
52 | Nieprawidłowa lokalizacja ścieżki modu
53 | Nie mogliśmy znaleźć lokalizacji moda. Czy folder został usunięty, lub jest dostępny na liście modów offline?
54 |
55 |
56 | Nie udało się odinstalować moda %1$s. Błąd: %2$s.
57 | Instaluj
58 | Mod już zainstalowany w %1$s
59 | Podgląd
60 |
61 | Zobacz informacje
62 | Sprawdź brakujące zależności
63 | Zgłoś mod
64 | Zobacz temat na forum
65 | Zobacz Read Me
66 |
67 | Informacje
68 | Nazwa moda
69 | Autor
70 | Typ
71 | Katalog
72 | Pobierany URL
73 | Rozmiar do pobrania
74 | Nieznany
75 | Paczka Modów
76 | Read Me
77 |
78 |
79 | Zgłoś mod
80 | %1$s przez %2$s
81 | Proszę wybierz powód dlaczego zgłaszasz tą modyfikację. Jeżeli masz jakieś inne informacje, proszę wpisz je w polu tekstowym.
82 | Powód
83 | Opcjonalna wiadomość
84 | Szczegóły
85 | Konfiguracja świata
86 | Akceptuj
87 | Konfiguracja zapisana
88 |
89 |
90 | Po przez używanie tego serwisu, zgadzasz się na następujące warunki.
91 | Brak gwarancji
92 | Nie sklep z modami, ale wyszukiwarka modów
93 | Dostępna lista modyfikacji, jest podzbiorem modyfikacje znalezionych na forach Minetest. Kiedy pobierasz mod, nie pobierasz go z naszych serwerów ale z oryginalnego linku podanego przez autora. Z uwagi na to, nie możemy gwarantować że modyfikacje są bezpieczne. Nikt w szczególności nie sprawdza tych modów.
94 |
95 | Co chcesz zrobić?
96 | Jeżeli nie jesteś pewny co do bezpieczeństwa modyfikacji, sprawdź temat na forum. Sprawdź jaki jest stary, i co mówią w komentarzach.
97 |
98 | Zaakceptuj i instaluj
99 |
100 |
101 | O tej aplikacji
102 | Rozwijane przez rubenwardy (rubenwardy.com)
103 | Dziękuje ci Krock (aka SmallJoker) za stworzenie Krock\'s Mod Search, bota indeksującego na którym bazuje dostępna lista modów.
104 | Dziękuje ci DonBatman za wsparcie podczas rozwoju
105 | Logo aplikacji bazuje na logo Minetest które jest na licencji CC-BY-SA 3.0, utworzone przez erlehmann
106 | Ta aplikacja używa także wiele standardowych ikon Androida, które są na licencji CC-BY 4.0
107 | Wyszukaj gdziekolwiek
108 | Dziękuje następującym tłumaczom: mojemu przyjacielowi Soph (Francja), Dragonop (Hiszpania), Adrian (Niemcy), monolifed (Turcja), i muhdnurhidayat (Malezja).
109 | Disclaimer
110 | Napisy końcowe
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/values-tr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Minetest Modları
3 |
4 |
5 | Kullanılabilir harici depolama yok
6 | Minetest mod klasörü yaratılamadı
7 | Kapat
8 | Dünya yaratılamıyor
9 | Yapılandırmanız için bir dünya yaratmaya çalıştık ama işlem başarısız oldu.
10 | Minetest kurulu değil
11 | Her şey yolunda!
12 | Tüm gerekli bağımlılıkları kurulu.
13 |
14 | Ara
15 |
16 |
17 | %1$s Mod Kuruldu
18 | Kullanılabilir Modlar
19 | Hey! Bize biraz yıldız vermek ister misiniz?
20 | Değerlendir
21 | Hayır
22 | Dünya simgesine tıklayarak bir mod etkinleştir.
23 |
24 |
25 | Mod kuruluyor…
26 | %1$s Kuruldu.
27 | %1$s Kuruluyor…
28 | Bağlanılıyor…
29 | İndiriliyor…
30 | Ayıklanıyor…
31 | %1$s modu kurulamadı. Hata: %2$s.
32 | %1$s modu kaldırılamadı. Hata: %2$s.
33 | Kullanılabilir mod listesi indirilemedi. Hata: %1$s.
34 |
35 | Gerekli Modları Kur
36 | Eğer bir modun güvenliliği konusunda emin değilseniz, onun forum konusuna bakın. Yorumların ne dediğine ve konunun ne kadar eski olduğuna bakın.
37 |
38 | Kabul Et ve Yükle
39 |
40 |
41 | Bu Uygulama Hakkında
42 | Katkılar
43 | Rubenwardy (rubenwardy.com) tarafından geliştirildi
44 | Geliştirme sırasında geribildirim için DonBatman\'a teşekkürler
45 | Başka Yerde Ara
46 | Bu eksik bağımlılıkları kurmak ister misiniz?
47 | Ne yazık ki, gerekli modların tamamını bulamadık :(
48 | Ne yazık ki, gerekli modların hiçbirini bulamadık :(
49 | Mod Ayrıntısı
50 | Kur
51 | Kaldır
52 |
53 | Mod zaten %1$s \'de kurulu
54 | Göster
55 |
56 | Bilgileri Göster
57 | Eksik bağımlılıkları doğrulayın
58 | Modu Bildir
59 | Forum Konusunu Göster
60 | Beni Oku\'yu Göster
61 |
62 | Bu mod tanınmış bir yazardan.
63 | Bu mod tanınmış bir yazar tarafından yapılmamış.
64 | Bu modun kaynağı belirlenemiyor.
65 |
66 | Geçersiz Mod
67 | O modu bulamadık. Silinmiş mi?
68 | Geçersiz Mod Yeri veya Konumu
69 | Bilgi
70 | Mod Adı
71 | Yazar
72 | Tür
73 | Klasör
74 | İndirme URL\'si
75 | İndirme Boyutu
76 | Bilinmiyor
77 | Mod Paketi
78 | Beni Oku
79 |
80 |
81 | Modu Bildir
82 | %1$s - %2$s
83 | Neden
84 | İsteğe Bağlı Mesaj
85 | Ayrıntılar
86 | Dünya Yapılandırması
87 | Kabul Et
88 | Kaydedilmiş yapılandırma
89 |
90 |
91 | Yasal Uyarı
92 | Garantisiz
93 | Ne yapabilirsiniz?
94 | Kullanılabilir harici depolama olmadığından Minetest klasörünü bulamadık. Harici depolama aygıtınızdaki paylaşılan bir dosya konumudur, ve bir SD kart anlamına gelmez.
95 | Aygıtınızda modlar için bir klasör yoktu, bu yüzden bir tane yaratmaya çalıştık. Ancak, başarısız oldu. Sistem bu uygulamanın ona erişimini reddediyor olabilir. Minetest\'i çalıştırmayı deneyin.
96 | Uygulama mağazasından bu uygulamayı kullanmadan önce Minetest\'i kurmanız önerilir!
97 | UYARI: Minetest\'i en az bir kere açtığınızdan emin olun, bu modların bazıları paketli gelmeli.
98 |
99 | Mod konumunu bulamadık. Klasör silindi mi veya kullanılabilir mod listesi çevrim dışı mı?
100 |
101 |
102 | Lütfen bu modu bildirme nedeninizi seçin. Başka bir bilginiz varsa, lütfen onu metin olarak girin.
103 | Bu hizmeti kullanarak, aşağıdaki şartları ve koşulları kabul edersiniz.
104 | Bir Mod Mağazası değil, sadece bir Mod Bulucu
105 | "Kullanılabilir olarak listelenen modlar Minetest forumlarında bulunan modların bir kısmıdır. Bir modu indirdiğinizde onu bizim sunucularımızdan indirmezsiniz bunun yerine yazarın belirttiği özgün bağlantıdan indirirsiniz. Bu yüzden, modların güvenliliğine güvence veremeyiz. Belirli hiç kimse bu modları denetlemez."
106 |
107 | Kullanılabilir modlar listesinin temel aldığı tarayıcı olan Krock\'un Mod Aramasını yarattığı için Krock\'a (Smalljoker) teşekkürler.
108 | Uygulama logosu, erlehmann tarafından yaratılmış ve CC-BY-SA 3.0 olan Minetest logosunu temel alır
109 | Bu uygulama CC-BY 4.0 olan birkaç standart Android simgesi de kullanır
110 | Aşağıdaki çevirmenlere teşekkürler: arkadaşım Soph (Fransızca), Dragonop (İspanyolca), Adrian (Almanca), monolifed (Türkçe), ve muhdnurhidayat (Malaya).
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 | >
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w900dp/refs.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 | - @layout/mod_list_twopane
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #08a320
4 | #067316
5 | #21a334
6 | @color/colorPrimaryDark
7 | @color/colorAccent
8 | #fff
9 | #fff
10 | @color/colorAccent
11 | @color/colorAccent
12 | #f44336
13 | #fbfbfb
14 | #e5e5e5
15 | #37000000
16 | #424242
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 200dp
4 | 400dp
5 | 3dp
6 | 16dp
7 | 8dp
8 | 8dp
9 | 8dp
10 | 4dp
11 |
12 | 16dp
13 | 16dp
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
16 |
17 |
20 |
21 |
29 |
30 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/test/java/com/rubenwardy/minetestmodmanager/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.rubenwardy.minetestmodmanager;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.10'
5 | repositories {
6 | jcenter()
7 | maven {
8 | url 'https://maven.google.com/'
9 | name 'Google'
10 | }
11 | google()
12 | }
13 | dependencies {
14 | classpath 'com.android.tools.build:gradle:3.4.1'
15 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
16 |
17 | // NOTE: Do not place your application dependencies here; they belong
18 | // in the individual module build.gradle files
19 | }
20 | }
21 |
22 | allprojects {
23 | repositories {
24 | jcenter()
25 | maven {
26 | url 'https://maven.google.com/'
27 | name 'Google'
28 | }
29 | }
30 | }
31 |
32 |
33 | task clean(type: Delete) {
34 | delete rootProject.buildDir
35 | }
36 |
--------------------------------------------------------------------------------
/gradle-app.setting:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rubenwardy/mtmods4android/90792b7ad86d8e2e01edf1794d8a31e018eadc7f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jun 25 01:40:11 BST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/misc/notification_icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
187 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
--------------------------------------------------------------------------------