1
0

Compare commits

...

20 Commits

Author SHA1 Message Date
luk3yx
f8bbed282e Don't use file download timeout for fetching ContentDB packages 2024-06-02 05:39:29 -04:00
7a9b79565b allow "-" on mods name for allowed chars 2024-06-02 05:22:07 -04:00
8eb09a5aa1 Add CSM restriction flag to block third party CSMs (#162) 2024-06-02 05:13:31 -04:00
bc3f43705c Handle translation files 2024-06-02 05:11:35 -04:00
6b22510752 Minor changes update gradle 2024-06-02 05:10:09 -04:00
8d4b921749 Initialise some variables in v7p becouse C++ standart
* the mapgen v7p has its own settings, to customise use v7 normal
2024-06-02 05:03:22 -04:00
67bd44f9fb Update the VCPKG version in Actions 2024-06-02 05:02:16 -04:00
Maksym H
1eb6b1dcb0 Disable desynchronize_mapblock_texture_animation by default 2024-06-02 05:00:47 -04:00
Deve
062f2e3613 Remove unused function that fails to build with new C++ 2024-06-02 04:58:34 -04:00
luk3yx
0eb18780e4 Add "hide_game = true" option to game.conf (#152) 2024-06-02 04:57:52 -04:00
Bektur
1538e5bc99 Android: update Kotlin part (#150) 2024-06-02 04:56:31 -04:00
a6f200ff21 Disable stereo mode support but dont over stereo mode on desktop
* Disable stereo mode support
* Fix stereo mode on desktop
* NOTE> this seems needs up to date irrlicht ?
2024-06-02 04:38:41 -04:00
f0d4e9bede Apple: minor update, change copyright XD 2024-06-02 04:37:32 -04:00
64ddc4065a Improve InfoText positioning on the screen 2024-06-02 04:22:52 -04:00
bf186d81b1 Avoid a crash in drawMeshNode() after reading out of array
* backported from b201316aed
2024-06-02 04:20:34 -04:00
Deve
f783bdb170 Fixed possible crash when close event is received during media loading 2024-06-02 04:19:38 -04:00
Maksym H
80d583e219 Android: update deps 2024-06-02 04:19:25 -04:00
d78e41a0f0 Fix compiler warnings in srp.cpp 2024-06-02 04:15:54 -04:00
005debcd8a adapt and set proper Fix curl deprecation warnings
* now curls still can be 7.19 and if 7.56.0 is detected then we used multipart
* commit 99209cd5d7
2024-06-02 04:12:41 -04:00
b7ad037647 update CI - specify 32bit for older debians build test 2024-06-02 01:17:51 -04:00
106 changed files with 891 additions and 611 deletions

View File

@ -260,8 +260,8 @@ jobs:
name: VS 2022 ${{ matrix.config.arch }}-${{ matrix.type }} name: VS 2022 ${{ matrix.config.arch }}-${{ matrix.type }}
runs-on: windows-2022 runs-on: windows-2022
env: env:
VCPKG_VERSION: af2287382b1991dbdcb7e5112d236f3323b9dd7a VCPKG_VERSION: a42af01b72c28a8e1d7b48107b33e4f286a55ef6
# 2022.03.10 # 2023.11.20
vcpkg_packages: irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit gmp jsoncpp vcpkg_packages: irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit gmp jsoncpp
strategy: strategy:
fail-fast: false fail-fast: false

View File

@ -70,9 +70,29 @@ build:alpine-319:
# Jessie # Jessie
build:debian-8: build:debian-8-64:
<<: *build_definition <<: *build_definition
image: debian:8 image: amd64/debian:8
before_script:
- echo "" > /etc/apt/apt.conf.d/50venenuxcustom
- echo "APT::Get::AllowUnauthenticated \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- echo "Acquire::AllowInsecureRepositories \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- echo "Acquire::AllowDowngradeToInsecureRepositories \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- echo "Acquire::AllowReleaseInfoChange::Suite \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- echo "Acquire::Check-Valid-Until \"false\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- echo "Acquire::Languages \"en\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- echo "Aptitude::CmdLine::Ignore-Trust-Violations \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom
- rm -rf /etc/apt/sources.list
- echo "deb http://archive.debian.org/debian/ jessie main contrib" > /etc/apt/sources.list.d/50debianoficial.list
- echo "deb http://archive.debian.org/debian/ jessie-backports main contrib non-free" >> /etc/apt/sources.list.d/50debianoficial.list
- echo "deb http://deb.freexian.com/extended-lts jessie main contrib non-free" >> /etc/apt/sources.list.d/50debianoficial.list
- DEBIAN_FRONTEND=noninteractive apt-get update -y || true
- DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes install build-essential cmake pkg-config cmake-data debhelper lsb-release gettext libbz2-dev libcurl4-gnutls-dev libnl-genl-3-dev libnl-3-dev librtmp-dev libidn11-dev libncurses-dev libfreetype6-dev libglu1-mesa-dev libgmp-dev libirrlicht-dev libjpeg-dev libleveldb-dev libluajit-5.1-dev liblua5.1-dev libogg-dev libopenal-dev libpng-dev libpq-dev libhiredis-dev libspatialindex-dev libsqlite3-dev libvorbis-dev libx11-dev libxxf86vm-dev libpq-dev postgresql-server-dev-all libhiredis-dev zlib1g-dev doxygen libxrandr-dev x11proto-xf86vidmode-dev
- DEBIAN_FRONTEND=noninteractive apt-get -y --force-yes -t jessie-backports install libjsoncpp-dev
build:debian-8-32:
<<: *build_definition
image: i386/debian:8
before_script: before_script:
- echo "" > /etc/apt/apt.conf.d/50venenuxcustom - echo "" > /etc/apt/apt.conf.d/50venenuxcustom
- echo "APT::Get::AllowUnauthenticated \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom - echo "APT::Get::AllowUnauthenticated \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom
@ -92,9 +112,9 @@ build:debian-8:
# Stretch # Stretch
build:debian-9: build:debian-9-32:
<<: *build_definition <<: *build_definition
image: debian:9 image: i386/debian:9
before_script: before_script:
- echo "" > /etc/apt/apt.conf.d/50venenuxcustom - echo "" > /etc/apt/apt.conf.d/50venenuxcustom
- echo "APT::Get::AllowUnauthenticated \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom - echo "APT::Get::AllowUnauthenticated \"true\";" >> /etc/apt/apt.conf.d/50venenuxcustom

View File

@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
android { android {
compileSdkVersion 33 compileSdkVersion 34
buildToolsVersion '33.0.2' buildToolsVersion '34.0.0'
ndkVersion '25.2.9519653' ndkVersion '25.2.9519653'
defaultConfig { defaultConfig {
applicationId 'com.multicraft.game' applicationId 'com.multicraft.game'
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 34
versionName "${versionMajor}.${versionMinor}.${versionPatch}" versionName "${versionMajor}.${versionMinor}.${versionPatch}"
versionCode project.versionCode versionCode project.versionCode
} }
@ -100,7 +100,7 @@ tasks.register('prepareAssetsFiles') {
tasks.register('zipAssetsFiles', Zip) { tasks.register('zipAssetsFiles', Zip) {
dependsOn prepareAssetsFiles dependsOn prepareAssetsFiles
archiveFileName = 'assets.zip' archiveFileName = 'assets.zip'
destinationDirectory = file('src/main/assets/data') destinationDirectory = file('src/main/assets')
from('build/assets/Files') from('build/assets/Files')
} }
@ -125,7 +125,8 @@ dependencies {
/* Third-party libraries */ /* Third-party libraries */
implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.appcompat:appcompat-resources:1.6.1' implementation 'androidx.appcompat:appcompat-resources:1.6.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' implementation("androidx.browser:browser:1.6.0")
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
implementation 'androidx.work:work-runtime-ktx:2.8.1' implementation 'androidx.work:work-runtime-ktx:2.8.1'
implementation 'com.google.android.material:material:1.9.0' implementation 'com.google.android.material:material:1.10.0'
} }

View File

@ -28,7 +28,6 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="false"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
@ -42,8 +41,8 @@
android:value="3.0" /> android:value="3.0" />
<activity <activity
android:name="com.multicraft.game.MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize" android:configChanges="orientation|keyboardHidden|navigation|screenSize|screenLayout"
android:exported="true" android:exported="true"
android:maxAspectRatio="3.0" android:maxAspectRatio="3.0"
android:screenOrientation="sensorLandscape" android:screenOrientation="sensorLandscape"
@ -55,8 +54,8 @@
</activity> </activity>
<activity <activity
android:name="com.multicraft.game.GameActivity" android:name=".GameActivity"
android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize" android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize|screenLayout|uiMode"
android:exported="true" android:exported="true"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTask" android:launchMode="singleTask"
@ -72,6 +71,19 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".dialogs.ConnectionDialog"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="sensorLandscape"
android:theme="@style/CustomDialog" />
<activity
android:name=".dialogs.RestartDialog"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="sensorLandscape"
android:theme="@style/CustomDialog" />
</application> </application>
</manifest> </manifest>

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@ -20,11 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
package com.multicraft.game package com.multicraft.game
import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Configuration.HARDKEYBOARDHIDDEN_NO
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.*
import android.text.InputType import android.text.InputType
import android.view.* import android.view.*
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
@ -33,12 +31,15 @@ import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsIntent.SHARE_STATE_OFF
import com.multicraft.game.MainActivity.Companion.radius import com.multicraft.game.MainActivity.Companion.radius
import com.multicraft.game.databinding.InputTextBinding import com.multicraft.game.databinding.*
import com.multicraft.game.databinding.MultilineInputBinding
import com.multicraft.game.helpers.* import com.multicraft.game.helpers.*
import com.multicraft.game.helpers.ApiLevelHelper.isOreo import com.multicraft.game.helpers.ApiLevelHelper.isOreo
import org.libsdl.app.SDLActivity import org.libsdl.app.SDLActivity
import java.util.*
import kotlin.system.exitProcess
class GameActivity : SDLActivity() { class GameActivity : SDLActivity() {
companion object { companion object {
@ -54,21 +55,21 @@ class GameActivity : SDLActivity() {
private var messageReturnValue = "" private var messageReturnValue = ""
private var hasKeyboard = false private var hasKeyboard = false
override fun getLibraries() = arrayOf("MultiCraft")
override fun getLibraries(): Array<String> { override fun getMainSharedObject() =
return arrayOf( "${getContext().applicationInfo.nativeLibraryDir}/libMultiCraft.so"
"MultiCraft"
)
}
override fun getMainSharedObject(): String {
return getContext().applicationInfo.nativeLibraryDir + "/libMultiCraft.so"
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) try {
super.onCreate(savedInstanceState)
} catch (e: Error) {
exitProcess(0)
} catch (e: Exception) {
exitProcess(0)
}
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
hasKeyboard = resources.configuration.hardKeyboardHidden == HARDKEYBOARDHIDDEN_NO hasKeyboard = hasHardKeyboard()
} }
override fun onWindowFocusChanged(hasFocus: Boolean) { override fun onWindowFocusChanged(hasFocus: Boolean) {
@ -88,15 +89,13 @@ class GameActivity : SDLActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (hasKeyboard) if (hasKeyboard) keyboardEvent(true)
keyboardEvent(hasKeyboard)
window.makeFullScreen() window.makeFullScreen()
} }
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
val statusKeyboard = val statusKeyboard = hasHardKeyboard()
resources.configuration.hardKeyboardHidden == HARDKEYBOARDHIDDEN_NO
if (hasKeyboard != statusKeyboard) { if (hasKeyboard != statusKeyboard) {
hasKeyboard = statusKeyboard hasKeyboard = statusKeyboard
keyboardEvent(hasKeyboard) keyboardEvent(hasKeyboard)
@ -137,8 +136,8 @@ class GameActivity : SDLActivity() {
editText.inputType = inputType editText.inputType = inputType
editText.setSelection(editText.text?.length ?: 0) editText.setSelection(editText.text?.length ?: 0)
// for Android OS // for Android OS
editText.setOnEditorActionListener { _: TextView?, KeyCode: Int, _: KeyEvent? -> editText.setOnEditorActionListener { _: TextView?, keyCode: Int, _: KeyEvent? ->
if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) {
imm.hideSoftInputFromWindow(editText.windowToken, 0) imm.hideSoftInputFromWindow(editText.windowToken, 0)
messageReturnValue = editText.text.toString() messageReturnValue = editText.text.toString()
alertDialog.dismiss() alertDialog.dismiss()
@ -147,16 +146,17 @@ class GameActivity : SDLActivity() {
} }
return@setOnEditorActionListener false return@setOnEditorActionListener false
} }
// for Chrome OS if (isChromebook()) {
editText.setOnKeyListener { _: View?, KeyCode: Int, _: KeyEvent? -> editText.setOnKeyListener { _: View?, keyCode: Int, _: KeyEvent? ->
if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) {
imm.hideSoftInputFromWindow(editText.windowToken, 0) imm.hideSoftInputFromWindow(editText.windowToken, 0)
messageReturnValue = editText.text.toString() messageReturnValue = editText.text.toString()
alertDialog.dismiss() alertDialog.dismiss()
isInputActive = false isInputActive = false
return@setOnKeyListener true return@setOnKeyListener true
}
return@setOnKeyListener false
} }
return@setOnKeyListener false
} }
binding.input.setEndIconOnClickListener { binding.input.setEndIconOnClickListener {
imm.hideSoftInputFromWindow(editText.windowToken, 0) imm.hideSoftInputFromWindow(editText.windowToken, 0)
@ -174,7 +174,7 @@ class GameActivity : SDLActivity() {
// should be above `show()` // should be above `show()`
alertWindow.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE) alertWindow.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE)
alertDialog.show() alertDialog.show()
if (!resources.getBoolean(R.bool.isTablet)) if (!isTablet())
alertWindow.makeFullScreenAlert() alertWindow.makeFullScreenAlert()
alertDialog.setOnCancelListener { alertDialog.setOnCancelListener {
window.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN) window.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN)
@ -200,8 +200,8 @@ class GameActivity : SDLActivity() {
editText.setSelection(editText.text?.length ?: 0) editText.setSelection(editText.text?.length ?: 0)
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
// for Android OS // for Android OS
editText.setOnEditorActionListener { _: TextView?, KeyCode: Int, _: KeyEvent? -> editText.setOnEditorActionListener { _: TextView?, keyCode: Int, _: KeyEvent? ->
if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) {
imm.hideSoftInputFromWindow(editText.windowToken, 0) imm.hideSoftInputFromWindow(editText.windowToken, 0)
messageReturnValue = editText.text.toString() messageReturnValue = editText.text.toString()
alertDialog.dismiss() alertDialog.dismiss()
@ -210,16 +210,17 @@ class GameActivity : SDLActivity() {
} }
return@setOnEditorActionListener false return@setOnEditorActionListener false
} }
// for Chrome OS if (isChromebook()) {
editText.setOnKeyListener { _: View?, KeyCode: Int, _: KeyEvent? -> editText.setOnKeyListener { _: View?, keyCode: Int, _: KeyEvent? ->
if (KeyCode == KeyEvent.KEYCODE_ENTER || KeyCode == KeyEvent.KEYCODE_ENDCALL) { if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_ENDCALL) {
imm.hideSoftInputFromWindow(editText.windowToken, 0) imm.hideSoftInputFromWindow(editText.windowToken, 0)
messageReturnValue = editText.text.toString() messageReturnValue = editText.text.toString()
alertDialog.dismiss() alertDialog.dismiss()
isInputActive = false isInputActive = false
return@setOnKeyListener true return@setOnKeyListener true
}
return@setOnKeyListener false
} }
return@setOnKeyListener false
} }
binding.multiInput.setEndIconOnClickListener { binding.multiInput.setEndIconOnClickListener {
imm.hideSoftInputFromWindow(editText.windowToken, 0) imm.hideSoftInputFromWindow(editText.windowToken, 0)
@ -237,7 +238,7 @@ class GameActivity : SDLActivity() {
val alertWindow = alertDialog.window!! val alertWindow = alertDialog.window!!
alertWindow.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE) alertWindow.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE)
alertDialog.show() alertDialog.show()
if (!resources.getBoolean(R.bool.isTablet)) if (!isTablet())
alertWindow.makeFullScreenAlert() alertWindow.makeFullScreenAlert()
alertDialog.setOnCancelListener { alertDialog.setOnCancelListener {
window.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN) window.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN)
@ -270,9 +271,13 @@ class GameActivity : SDLActivity() {
@Suppress("unused") @Suppress("unused")
fun openURI(uri: String?) { fun openURI(uri: String?) {
val builder = CustomTabsIntent.Builder()
builder.setShareState(SHARE_STATE_OFF)
.setStartAnimations(this, R.anim.slide_in_bottom, R.anim.slide_out_top)
.setExitAnimations(this, R.anim.slide_in_top, R.anim.slide_out_bottom)
val customTabsIntent = builder.build()
try { try {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)) customTabsIntent.launchUrl(this, Uri.parse(uri))
startActivity(browserIntent)
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
} }
@ -292,7 +297,7 @@ class GameActivity : SDLActivity() {
@Suppress("unused") @Suppress("unused")
fun getSecretKey(key: String): String { fun getSecretKey(key: String): String {
return "Stub" return key
} }
@Suppress("unused") @Suppress("unused")

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@ -22,18 +22,25 @@ package com.multicraft.game
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.LayerDrawable
import android.os.Bundle import android.os.Bundle
import android.view.* import android.provider.Settings.ACTION_WIFI_SETTINGS
import android.provider.Settings.ACTION_WIRELESS_SETTINGS
import android.view.RoundedCorner
import android.view.WindowManager
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.BlendModeColorFilterCompat import androidx.lifecycle.Observer
import androidx.core.graphics.BlendModeCompat import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.* import androidx.lifecycle.lifecycleScope
import androidx.work.WorkInfo import androidx.work.WorkInfo
import com.multicraft.game.databinding.ActivityMainBinding import com.multicraft.game.databinding.ActivityMainBinding
import com.multicraft.game.dialogs.ConnectionDialog
import com.multicraft.game.helpers.* import com.multicraft.game.helpers.*
import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12 import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12
import com.multicraft.game.helpers.ApiLevelHelper.isPie
import com.multicraft.game.helpers.PreferenceHelper.TAG_BUILD_VER import com.multicraft.game.helpers.PreferenceHelper.TAG_BUILD_VER
import com.multicraft.game.helpers.PreferenceHelper.getStringValue import com.multicraft.game.helpers.PreferenceHelper.getStringValue
import com.multicraft.game.helpers.PreferenceHelper.set import com.multicraft.game.helpers.PreferenceHelper.set
@ -49,11 +56,14 @@ class MainActivity : AppCompatActivity() {
private var externalStorage: File? = null private var externalStorage: File? = null
private val sep = File.separator private val sep = File.separator
private lateinit var prefs: SharedPreferences private lateinit var prefs: SharedPreferences
private lateinit var restartStartForResult: ActivityResultLauncher<Intent>
private lateinit var connStartForResult: ActivityResultLauncher<Intent>
private val versionCode = BuildConfig.VERSION_CODE private val versionCode = BuildConfig.VERSION_CODE
private val versionName = "${BuildConfig.VERSION_NAME}+$versionCode" private val versionName = "${BuildConfig.VERSION_NAME}+$versionCode"
companion object { companion object {
var radius = 0 var radius = 0
const val NO_SPACE_LEFT = "ENOSPC"
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -61,30 +71,34 @@ class MainActivity : AppCompatActivity() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
}
})
connStartForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
checkAppVersion()
}
restartStartForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == RESULT_OK)
finishApp(true)
else
finishApp(false)
}
try { try {
prefs = PreferenceHelper.init(this) prefs = PreferenceHelper.init(this)
externalStorage = getExternalFilesDir(null) externalStorage = getExternalFilesDir(null)
if (filesDir == null || cacheDir == null || externalStorage == null) listOf(filesDir, cacheDir, externalStorage).requireNoNulls()
throw IOException("Bad disk space state")
checkConnection() checkConnection()
} catch (e: Exception) { // Storage -> IOException, Prefs -> GeneralSecurityException } catch (e: Exception) {
showRestartDialog(!e.message!!.contains("ENOPSC")) val isRestart = e.message?.contains(NO_SPACE_LEFT) != true
showRestartDialog(restartStartForResult, isRestart)
} }
} }
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@Suppress("DEPRECATION")
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 104)
checkAppVersion()
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
// Prevent abrupt interruption when copy game files from assets
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
window.makeFullScreen() window.makeFullScreen()
@ -97,81 +111,66 @@ class MainActivity : AppCompatActivity() {
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
super.onAttachedToWindow() super.onAttachedToWindow()
if (isAndroid12()) { if (isPie()) {
val insets = window.decorView.rootWindowInsets val cutout = window.decorView.rootWindowInsets.displayCutout
if (insets != null) { if (cutout != null) {
val tl = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT) radius = 40
radius = tl?.radius ?: 0 }
if (isAndroid12()) {
val insets = window.decorView.rootWindowInsets
if (insets != null) {
val tl = insets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT)
radius = tl?.radius ?: if (cutout != null) 40 else 0
}
} }
} }
} val animation = binding.loadingAnim.drawable as AnimationDrawable
animation.start()
// interface
private fun showProgress(textMessage: Int, progress: Int) {
if (binding.progressBar.visibility == View.GONE) {
binding.tvProgress.setText(textMessage)
binding.progressCircle.visibility = View.GONE
binding.progressBar.visibility = View.VISIBLE
binding.progressBar.progress = 0
} else if (progress > 0) {
val progressMessage = "${getString(textMessage)} $progress%"
binding.tvProgress.text = progressMessage
binding.progressBar.progress = progress
// colorize the progress bar
val progressBarDrawable =
(binding.progressBar.progressDrawable as LayerDrawable).getDrawable(0)
val progressDrawable = (progressBarDrawable as LayerDrawable).getDrawable(1)
val color = Color.rgb(255 - progress * 2, progress * 2, 25)
progressDrawable.colorFilter =
BlendModeColorFilterCompat.createBlendModeColorFilterCompat(
color, BlendModeCompat.SRC_IN
)
}
} }
private fun startNative() { private fun startNative() {
val initLua = File(filesDir, "builtin${sep}mainmenu${sep}init.lua") val initLua = File(filesDir, "builtin${sep}mainmenu${sep}init.lua")
if (initLua.exists() && initLua.canRead()) { if (initLua.exists() && initLua.canRead()) {
val intent = Intent(this, GameActivity::class.java) val intent = Intent(this, GameActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent) startActivity(intent)
} else { } else {
prefs[TAG_BUILD_VER] = "0" prefs[TAG_BUILD_VER] = "0"
showRestartDialog() showRestartDialog(restartStartForResult)
} }
} }
private fun prepareToRun() { private fun prepareToRun() {
binding.tvProgress.setText(R.string.preparing) val filesList = mutableListOf<File>().apply {
binding.progressCircle.visibility = View.VISIBLE addAll(listOf(
binding.progressBar.visibility = View.GONE "builtin",
val filesList = listOf( "client${sep}shaders",
File(externalStorage, "debug.txt"), "fonts",
File(filesDir, "builtin"), "games${sep}default",
File(filesDir, "client"), "textures${sep}base"
File(filesDir, "fonts"), ).map { File(filesDir, it) })
File(filesDir, "textures") }
)
val zips = assets.list("data")!!.toList() val zips = mutableListOf("assets.zip")
lifecycleScope.launch { lifecycleScope.launch {
filesList.forEach { it.deleteRecursively() } filesList.forEach { it.deleteRecursively() }
zips.forEach { zips.forEach {
try { try {
assets.open("data$sep$it").use { input -> assets.open(it).use { input ->
File(cacheDir, it).copyInputStreamToFile(input) File(cacheDir, it).copyInputStreamToFile(input)
} }
} catch (e: IOException) { } catch (e: IOException) {
runOnUiThread { showRestartDialog(!e.message!!.contains("ENOSPC")) } val isNotEnoughSpace = e.message!!.contains(NO_SPACE_LEFT)
runOnUiThread { showRestartDialog(restartStartForResult, !isNotEnoughSpace) }
return@forEach return@forEach
} }
} }
try { try {
startUnzipWorker(zips) startUnzipWorker(zips.toTypedArray())
} catch (e: Exception) { } catch (e: Exception) {
runOnUiThread { showRestartDialog() } runOnUiThread { showRestartDialog(restartStartForResult) }
} }
} }
} }
@ -184,31 +183,47 @@ class MainActivity : AppCompatActivity() {
prepareToRun() prepareToRun()
} }
private fun showConnectionDialog() {
val intent = Intent(this, ConnectionDialog::class.java)
val startForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
when (it.resultCode) {
RESULT_OK -> connStartForResult.launch(Intent(ACTION_WIFI_SETTINGS))
RESULT_FIRST_USER -> connStartForResult.launch(Intent(ACTION_WIRELESS_SETTINGS))
else -> checkAppVersion()
}
}
startForResult.launch(intent)
}
// check connection available // check connection available
private fun checkConnection() = lifecycleScope.launch { private fun checkConnection() = lifecycleScope.launch {
val result = isConnected() if (isConnected()) checkAppVersion()
if (result) checkAppVersion()
else try { else try {
showConnectionDialog { checkAppVersion() } showConnectionDialog()
} catch (e: Exception) { } catch (e: Exception) {
checkAppVersion() checkAppVersion()
} }
} }
private fun startUnzipWorker(file: List<String>) { private fun startUnzipWorker(file: Array<String>) {
val viewModelFactory = WorkerViewModelFactory(application, file.toTypedArray()) val viewModelFactory = WorkerViewModelFactory(application, file)
val viewModel = ViewModelProvider(this, viewModelFactory)[WorkerViewModel::class.java] val viewModel = ViewModelProvider(this, viewModelFactory)[WorkerViewModel::class.java]
viewModel.unzippingWorkObserver viewModel.unzippingWorkObserver
.observe(this, Observer { workInfo -> .observe(this, Observer { workInfo ->
if (workInfo == null) if (workInfo == null)
return@Observer return@Observer
val progress = workInfo.progress.getInt(PROGRESS, 0) val progress = workInfo.progress.getInt(PROGRESS, 0)
showProgress(R.string.loading, progress) if (progress > 0) {
val progressMessage = "${getString(R.string.loading)} $progress%"
binding.tvProgress.text = progressMessage
}
if (workInfo.state.isFinished) { if (workInfo.state.isFinished) {
if (workInfo.state == WorkInfo.State.FAILED) { if (workInfo.state == WorkInfo.State.FAILED) {
val isRestart = workInfo.outputData.getBoolean("restart", true) val isRestart = workInfo.outputData.getBoolean("restart", true)
showRestartDialog(isRestart) showRestartDialog(restartStartForResult, isRestart)
} else if (workInfo.state == WorkInfo.State.SUCCEEDED) { } else if (workInfo.state == WorkInfo.State.SUCCEEDED) {
prefs[TAG_BUILD_VER] = versionName prefs[TAG_BUILD_VER] = versionName
startNative() startNative()

View File

@ -0,0 +1,96 @@
/*
MultiCraft
Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.multicraft.game.dialogs
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager.SIM_STATE_READY
import android.view.View
import android.widget.LinearLayout
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import com.multicraft.game.databinding.ConnectionDialogBinding
import com.multicraft.game.helpers.ApiLevelHelper.isOreo
import com.multicraft.game.helpers.makeFullScreen
import org.libsdl.app.SDLActivity
class ConnectionDialog : AppCompatActivity() {
private fun isSimCardPresent(): Boolean {
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
if (!isOreo())
return telephonyManager.simState == SIM_STATE_READY
val isFirstSimPresent = telephonyManager.getSimState(0) == SIM_STATE_READY
val isSecondSimPresent = telephonyManager.getSimState(1) == SIM_STATE_READY
return isFirstSimPresent || isSecondSimPresent
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ConnectionDialogBinding.inflate(layoutInflater)
if (SDLActivity.isTablet()) {
val param = LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.WRAP_CONTENT,
0.5f
)
binding.connRoot.layoutParams = param
}
if (isSimCardPresent())
binding.mobile.visibility = View.VISIBLE
setContentView(binding.root)
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
}
})
binding.wifi.setOnClickListener {
setResult(Activity.RESULT_OK)
finish()
}
binding.mobile.setOnClickListener {
setResult(Activity.RESULT_FIRST_USER)
finish()
}
binding.ignore.setOnClickListener {
setResult(Activity.RESULT_CANCELED)
finish()
}
}
override fun onResume() {
super.onResume()
window.makeFullScreen()
}
override fun attachBaseContext(base: Context?) {
val configuration = Configuration(base?.resources?.configuration)
configuration.fontScale = 1.0f
applyOverrideConfiguration(configuration)
super.attachBaseContext(base)
}
}

View File

@ -0,0 +1,76 @@
/*
MultiCraft
Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.multicraft.game.dialogs
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.widget.LinearLayout
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import com.multicraft.game.databinding.RestartDialogBinding
import com.multicraft.game.helpers.makeFullScreen
import org.libsdl.app.SDLActivity
class RestartDialog : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = RestartDialogBinding.inflate(layoutInflater)
if (SDLActivity.isTablet()) {
val param = LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.WRAP_CONTENT,
0.5f
)
binding.restartRoot.layoutParams = param
}
setContentView(binding.root)
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
}
})
val message = intent.getStringExtra("message")!!
binding.errorDesc.text = message
binding.restart.setOnClickListener {
setResult(Activity.RESULT_OK)
finish()
}
binding.close.setOnClickListener {
setResult(Activity.RESULT_CANCELED)
finish()
}
}
override fun onResume() {
super.onResume()
window.makeFullScreen()
}
override fun attachBaseContext(base: Context?) {
val configuration = Configuration(base?.resources?.configuration)
configuration.fontScale = 1.0f
applyOverrideConfiguration(configuration)
super.attachBaseContext(base)
}
}

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@ -30,5 +30,7 @@ object ApiLevelHelper {
fun isOreo() = isGreaterOrEqual(O) fun isOreo() = isGreaterOrEqual(O)
fun isPie() = isGreaterOrEqual(P)
fun isAndroid12() = isGreaterOrEqual(S) fun isAndroid12() = isGreaterOrEqual(S)
} }

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@ -23,31 +23,22 @@ package com.multicraft.game.helpers
import android.app.* import android.app.*
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.res.Configuration
import android.net.ConnectivityManager import android.net.*
import android.net.NetworkCapabilities import android.os.*
import android.provider.Settings
import android.view.View
import android.view.Window import android.view.Window
import androidx.appcompat.app.AlertDialog import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.* import androidx.core.view.*
import com.multicraft.game.R import com.multicraft.game.*
import com.multicraft.game.databinding.ConnDialogBinding import com.multicraft.game.databinding.*
import com.multicraft.game.databinding.RestartDialogBinding import com.multicraft.game.dialogs.RestartDialog
import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12 import com.multicraft.game.helpers.ApiLevelHelper.isAndroid12
import java.io.File import com.multicraft.game.helpers.ApiLevelHelper.isMarshmallow
import java.io.InputStream import java.io.*
import kotlin.system.exitProcess import java.util.*
// Activity extensions // Activity extensions
fun AppCompatActivity.getIcon() = try {
packageManager.getApplicationIcon(packageName)
} catch (e: PackageManager.NameNotFoundException) {
ContextCompat.getDrawable(this, R.mipmap.ic_launcher)
}
fun Activity.finishApp(restart: Boolean) { fun Activity.finishApp(restart: Boolean) {
if (restart) { if (restart) {
val intent = Intent(this, this::class.java) val intent = Intent(this, this::class.java)
@ -61,72 +52,12 @@ fun Activity.finishApp(restart: Boolean) {
) )
) )
} }
exitProcess(0) finish()
} }
fun AppCompatActivity.defaultDialog(title: Int, view: View, style: Int = R.style.CustomDialog): AlertDialog { fun Activity.isConnected(): Boolean {
val builder = AlertDialog.Builder(this, style)
.setIcon(getIcon())
.setTitle(title)
.setCancelable(false)
.setView(view)
return builder.create()
}
fun AppCompatActivity.headlessDialog(
view: View,
style: Int = R.style.LightTheme,
isCancelable: Boolean = false
): AlertDialog {
val builder = AlertDialog.Builder(this, style)
.setCancelable(isCancelable)
.setView(view)
return builder.create()
}
fun AppCompatActivity.show(dialog: AlertDialog) {
window?.makeFullScreen()
if (!isFinishing) dialog.show()
}
fun AppCompatActivity.showConnectionDialog(listener: (() -> Unit)? = null) {
val binding = ConnDialogBinding.inflate(layoutInflater)
val dialog = defaultDialog(R.string.conn_title, binding.root)
binding.wifi.setOnClickListener {
dialog.dismiss()
startActivityForResult(
Intent(Settings.ACTION_WIFI_SETTINGS),
104
)
}
binding.mobile.setOnClickListener {
dialog.dismiss()
startActivityForResult(
Intent(Settings.ACTION_WIRELESS_SETTINGS),
104
)
}
binding.ignore.setOnClickListener {
dialog.dismiss()
listener?.invoke()
}
show(dialog)
}
fun AppCompatActivity.showRestartDialog(isRestart: Boolean = true) {
val message =
if (isRestart) getString(R.string.restart) else getString(R.string.no_space)
val binding = RestartDialogBinding.inflate(layoutInflater)
val dialog = headlessDialog(binding.root, R.style.CustomDialog)
binding.errorDesc.text = message
binding.close.setOnClickListener { finishApp(false) }
binding.restart.setOnClickListener { finishApp(true) }
show(dialog)
}
fun AppCompatActivity.isConnected(): Boolean {
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (ApiLevelHelper.isMarshmallow()) { if (isMarshmallow()) {
val activeNetwork = cm.activeNetwork ?: return false val activeNetwork = cm.activeNetwork ?: return false
val capabilities = cm.getNetworkCapabilities(activeNetwork) ?: return false val capabilities = cm.getNetworkCapabilities(activeNetwork) ?: return false
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
@ -136,6 +67,20 @@ fun AppCompatActivity.isConnected(): Boolean {
} }
} }
fun AppCompatActivity.showRestartDialog(
startForResult: ActivityResultLauncher<Intent>,
isRestart: Boolean = true
) {
val message =
if (isRestart) getString(R.string.restart) else getString(R.string.no_space)
val intent = Intent(this, RestartDialog::class.java)
intent.putExtra("message", message)
startForResult.launch(intent)
}
fun Activity.hasHardKeyboard() =
resources.configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
// Other extensions // Other extensions
fun File.copyInputStreamToFile(inputStream: InputStream) = fun File.copyInputStreamToFile(inputStream: InputStream) =
outputStream().use { fileOut -> inputStream.copyTo(fileOut, 8192) } outputStream().use { fileOut -> inputStream.copyTo(fileOut, 8192) }

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@ -26,6 +26,7 @@ import android.content.Context
import android.content.Context.NOTIFICATION_SERVICE import android.content.Context.NOTIFICATION_SERVICE
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.work.* import androidx.work.*
import com.multicraft.game.MainActivity.Companion.NO_SPACE_LEFT
import com.multicraft.game.R import com.multicraft.game.R
import com.multicraft.game.helpers.ApiLevelHelper.isOreo import com.multicraft.game.helpers.ApiLevelHelper.isOreo
import com.multicraft.game.helpers.copyInputStreamToFile import com.multicraft.game.helpers.copyInputStreamToFile
@ -83,7 +84,7 @@ class UnzipWorker(private val appContext: Context, workerParams: WorkerParameter
} }
Result.success() Result.success()
} catch (e: IOException) { } catch (e: IOException) {
val isNotEnoughSpace = e.localizedMessage!!.contains("ENOSPC") val isNotEnoughSpace = e.localizedMessage!!.contains(NO_SPACE_LEFT)
val out = Data.Builder() val out = Data.Builder()
.putBoolean("restart", !isNotEnoughSpace) .putBoolean("restart", !isNotEnoughSpace)
.build() .build()

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
MultiCraft MultiCraft
Copyright (C) 2014-2022 MoNTE48, Maksim Gamarnik <Maksym48@pm.me> Copyright (C) 2014-2023 MoNTE48, Maksim Gamarnik <Maksym48@pm.me>
Copyright (C) 2014-2022 ubulem, Bektur Mambetov <berkut87@gmail.com> Copyright (C) 2014-2023 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by

View File

@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL"; private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2; private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 28; private static final int SDL_MINOR_VERSION = 28;
private static final int SDL_MICRO_VERSION = 2; private static final int SDL_MICRO_VERSION = 4;
/* /*
// Display InputType.SOURCE/CLASS of events and devices // Display InputType.SOURCE/CLASS of events and devices
// //

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="100%p"
android:toYDelta="0%p" />

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="-100%p"
android:toYDelta="0%p" />

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="0%p"
android:toYDelta="100%p" />

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_mediumAnimTime"
android:fromYDelta="0%p"
android:toYDelta="-100%p" />

View File

@ -2,4 +2,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="@color/dark" /> <solid android:color="@color/dark" />
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape> </shape>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/green_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/green" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/red_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/red" />
</selector>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/yellow_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/yellow" />
</selector>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@android:id/background"
android:drawable="@drawable/progress_bar_bg" />
<item
android:id="@android:id/progress"
android:drawable="@drawable/progress_bar_fg" />
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

View File

@ -6,6 +6,6 @@
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24"> android:viewportHeight="24">
<path <path
android:fillColor="#008C80" android:fillColor="@color/green_mc"
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z" /> android:pathData="M3.4,20.4l17.45,-7.48c0.81,-0.35 0.81,-1.49 0,-1.84L3.4,3.6c-0.66,-0.29 -1.39,0.2 -1.39,0.91L2,9.12c0,0.5 0.37,0.93 0.87,0.99L17,12 2.87,13.88c-0.5,0.07 -0.87,0.5 -0.87,1l0.01,4.61c0,0.71 0.73,1.2 1.39,0.91z" />
</vector> </vector>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/loading_anim1"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim2"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim3"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim4"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim5"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim6"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim7"
android:duration="125" />
<item
android:drawable="@drawable/loading_anim8"
android:duration="125" />
</animation-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/custom_progress_bar" />
<item android:drawable="@drawable/progress_bar" />
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

View File

@ -1,34 +1,22 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ProgressBar <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/progress_bar" android:id="@+id/loading_anim"
style="@style/Widget.MaterialComponents.LinearProgressIndicator" android:layout_width="wrap_content"
android:layout_width="512dp" android:layout_height="wrap_content"
android:layout_height="64dp" app:srcCompat="@drawable/loading" />
android:layout_centerInParent="true"
android:indeterminate="false"
android:max="100"
android:progressDrawable="@drawable/progress"
android:visibility="gone" />
<ProgressBar
android:id="@+id/progress_circle"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerInParent="true"
android:indeterminate="true" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_progress" android:id="@+id/tv_progress"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/progress_circle" android:layout_marginTop="8dp"
android:layout_centerInParent="true" android:text="@string/preparing"
android:text="@string/loading"
android:textColor="@color/light" android:textColor="@color/light"
android:textSize="14sp" /> android:textSize="16sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="16dp"
android:paddingTop="24dp"
android:paddingRight="16dp"
android:text="@string/conn_message"
android:textColor="@color/grey_900" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/ignore"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="0.3"
android:text="@string/ignore"
android:textAllCaps="false"
android:textColor="@android:color/white"
app:backgroundTint="@color/red" />
<com.google.android.material.button.MaterialButton
android:id="@+id/mobile"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="0.4"
android:text="@string/conn_mobile"
android:textAllCaps="false"
android:textColor="@android:color/white"
app:backgroundTint="@color/green_mc" />
<com.google.android.material.button.MaterialButton
android:id="@+id/wifi"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="0.4"
android:text="@string/conn_wifi"
android:textAllCaps="false"
android:textColor="@android:color/white"
app:backgroundTint="@color/green_mc" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,78 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:gravity="center"
android:weightSum="1">
<LinearLayout
android:id="@+id/conn_root"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:background="@drawable/bg_common"
android:orientation="vertical"
android:padding="16dp"
tools:ignore="UselessParent">
<androidx.appcompat.widget.AppCompatTextView
style="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableStart="@mipmap/ic_dialog"
android:drawablePadding="8dp"
android:gravity="center"
android:text="@string/conn_title"
android:textColor="@color/grey_900" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="8dp"
android:text="@string/conn_message"
android:textColor="@color/grey_900"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ignore"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:layout_weight="0.33"
android:background="@drawable/btn_yellow"
android:text="@string/ignore"
android:textAllCaps="false"
android:textColor="@android:color/white" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/mobile"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:layout_weight="0.33"
android:background="@drawable/btn_green"
android:text="@string/conn_mobile"
android:textAllCaps="false"
android:textColor="@android:color/white"
android:visibility="gone" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/wifi"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:layout_weight="0.33"
android:background="@drawable/btn_green"
android:text="@string/conn_wifi"
android:textAllCaps="false"
android:textColor="@android:color/white" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -6,16 +6,17 @@
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/input" android:id="@+id/input"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/TextInputLayoutStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:background="@drawable/bg_input" android:background="@drawable/bg_input"
android:hint="@string/input_text" android:hint="@string/input_text"
android:padding="5dp" android:padding="4dp"
app:endIconDrawable="@drawable/ic_baseline_send" app:endIconDrawable="@drawable/ic_baseline_send"
app:endIconMode="custom" app:endIconMode="custom"
app:endIconTint="@null"> app:endIconTint="@null"
app:hintTextColor="@color/green_mc">
<com.multicraft.game.CustomEditText <com.multicraft.game.CustomEditText
android:id="@+id/editText" android:id="@+id/editText"

View File

@ -6,16 +6,17 @@
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/multiInput" android:id="@+id/multiInput"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" style="@style/TextInputLayoutStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:background="@drawable/bg_input" android:background="@drawable/bg_input"
android:hint="@string/input_text" android:hint="@string/input_text"
android:padding="5dp" android:padding="4dp"
app:endIconDrawable="@drawable/ic_baseline_send" app:endIconDrawable="@drawable/ic_baseline_send"
app:endIconMode="custom" app:endIconMode="custom"
app:endIconTint="@null"> app:endIconTint="@null"
app:hintTextColor="@color/green_mc">
<com.multicraft.game.CustomEditText <com.multicraft.game.CustomEditText
android:id="@+id/multiEditText" android:id="@+id/multiEditText"

View File

@ -1,34 +1,39 @@
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" xmlns:tools="http://schemas.android.com/tools"
android:layout_height="wrap_content"> android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:gravity="center"
android:weightSum="1">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:id="@+id/restart_root"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_weight="0.7"
android:background="@drawable/bg_common"
android:orientation="vertical" android:orientation="vertical"
android:paddingHorizontal="10dp" android:padding="16dp"
android:paddingTop="10dp"> tools:ignore="UselessParent">
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent" style="?android:attr/textAppearanceLarge"
android:layout_height="match_parent" android:layout_width="wrap_content"
android:layout_marginTop="8dp" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_gravity="center"
android:drawableStart="@mipmap/ic_dialog"
android:drawablePadding="8dp"
android:gravity="center" android:gravity="center"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/sorry" android:text="@string/sorry"
android:textSize="22sp" /> android:textColor="@color/grey_900" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal"> android:padding="8dp">
<ImageView <androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/restart" android:contentDescription="@string/restart"
@ -42,46 +47,40 @@
android:id="@+id/error_desc" android:id="@+id/error_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:minHeight="128dp" android:minHeight="128dp"
android:paddingStart="4dp" android:padding="4dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingBottom="4dp"
android:text="@string/restart" android:text="@string/restart"
android:textSize="15sp" /> android:textColor="@color/grey_900"
android:textSize="16sp" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp">
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/close" android:id="@+id/close"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="48dp"
android:layout_gravity="center" android:layout_margin="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:background="@drawable/btn_red"
android:text="@string/close_game" android:text="@string/close_game"
android:textStyle="bold" /> android:textAllCaps="false"
android:textColor="@android:color/white" />
<com.google.android.material.button.MaterialButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/restart" android:id="@+id/restart"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="48dp"
android:layout_gravity="center" android:layout_margin="8dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="4dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:background="@drawable/btn_green"
android:text="@string/restart_game" android:text="@string/restart_game"
android:textStyle="bold" /> android:textAllCaps="false"
android:textColor="@android:color/white" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- подготовка к запуску -->
<string name="preparing">Подготовка к запуску&#8230;</string> <string name="preparing">Подготовка к запуску&#8230;</string>
<string name="loading">Загрузка&#8230;</string> <string name="loading">Загрузка&#8230;</string>
<string name="notification_title">Загрузка MultiCraft</string> <string name="notification_title">Загрузка MultiCraft</string>
@ -9,9 +10,8 @@
<!-- диалог отсутствия подключения --> <!-- диалог отсутствия подключения -->
<string name="conn_title">Нет Интернет Подключения!</string> <string name="conn_title">Нет Интернет Подключения!</string>
<string name="conn_message">Для полноценной игры, MultiCraft требует подключение к Интернету.\nВ противном случае вам будет недоступно Обновление игры и режим Мультиплеера!</string> <string name="conn_message">Для полноценной игры, MultiCraft требует подключение к Интернету.\nВ противном случае Обновление игры и режим Мультиплеера будут недоступны!</string>
<string name="conn_mobile">3G/4G</string> <string name="ignore">Пропустить</string>
<string name="ignore">Игнорировать</string>
<!-- Crash --> <!-- Crash -->
<string name="sorry">Нам очень жаль!</string> <string name="sorry">Нам очень жаль!</string>

View File

@ -1,3 +0,0 @@
<resources>
<bool name="isTablet">true</bool>
</resources>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="CustomDialog" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="windowActionBar">false</item>
<item name="android:windowBackground">@drawable/bg</item>
<item name="android:windowFullscreen">true</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
<item name="fontFamily">@font/multicraftfont</item>
</style>
</resources>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="CustomDialog" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="windowActionBar">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFullscreen">true</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
<item name="fontFamily">@font/multicraftfont</item>
</style>
</resources>

View File

@ -1,3 +0,0 @@
<resources>
<bool name="isTablet">false</bool>
</resources>

View File

@ -1,8 +1,6 @@
<resources> <resources>
<color name="green">#008C80</color>
<color name="light">#FAFAFA</color> <color name="light">#FAFAFA</color>
<color name="dark">#121212</color> <color name="dark">#121212</color>
<color name="red">#FF1744</color>
<color name="green_mc">#32783C</color> <color name="green_mc">#32783C</color>
<color name="grey_900">#212121</color> <color name="grey_900">#212121</color>
</resources> </resources>

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" translatable="false">MultiCraft</string> <string name="app_name" translatable="false">MultiCraft</string>
<!-- preparation for start -->
<string name="preparing">Preparing to launch&#8230;</string> <string name="preparing">Preparing to launch&#8230;</string>
<string name="loading">Loading&#8230;</string> <string name="loading">Loading&#8230;</string>
<string name="notification_title">Loading MultiCraft</string> <string name="notification_title">Loading MultiCraft</string>
<string name="notification_description">Less than 1 minute&#8230;</string> <string name="notification_description">Less than 1 minute&#8230;</string>
<string name="input_text">Enter text</string> <string name="input_text">Enter text</string>
<string name="input_password">Enter password</string> <string name="input_password">Enter password</string>
@ -13,7 +14,7 @@
<string name="conn_title">No Internet Connection!</string> <string name="conn_title">No Internet Connection!</string>
<string name="conn_message">MultiCraft requires an Internet connection to use all game features.\nOtherwise, you will not get Updates and Multiplayer mode will be not available!</string> <string name="conn_message">MultiCraft requires an Internet connection to use all game features.\nOtherwise, you will not get Updates and Multiplayer mode will be not available!</string>
<string name="conn_wifi" translatable="false">Wi-Fi</string> <string name="conn_wifi" translatable="false">Wi-Fi</string>
<string name="conn_mobile">Mobile Data</string> <string name="conn_mobile" translatable="false">LTE</string>
<string name="ignore">Ignore</string> <string name="ignore">Ignore</string>
<!-- Crash --> <!-- Crash -->

View File

@ -1,27 +1,25 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="android:windowBackground">@drawable/bg</item> <item name="android:windowBackground">@drawable/bg</item>
<item name="android:windowFullscreen">true</item> <item name="android:windowFullscreen">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item> <item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
<item name="fontFamily">@font/multicraftfont</item> <item name="fontFamily">@font/multicraftfont</item>
<item name="colorPrimary">@color/green</item>
</style> </style>
<style name="LightTheme" parent="Theme.MaterialComponents.Light.Dialog"> <style name="CustomDialog" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:windowBackground">@drawable/bg_common</item> <item name="windowActionBar">false</item>
<item name="background">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item>
<item name="windowMinWidthMajor">0%</item> <item name="android:windowBackground">@android:color/transparent</item>
<item name="windowMinWidthMinor">0%</item> <item name="android:windowFullscreen">true</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
<item name="fontFamily">@font/multicraftfont</item>
</style> </style>
<style name="CustomDialog" parent="Theme.MaterialComponents.Light.Dialog.Alert"> <style name="FullScreenDialogStyle" parent="Theme.MaterialComponents.Light.Dialog">
<item name="android:windowBackground">@drawable/bg_common</item>
<item name="background">@android:color/transparent</item>
</style>
<style name="FullScreenDialogStyle" parent="Theme.MaterialComponents.DayNight.Dialog">
<item name="android:windowFullscreen">true</item> <item name="android:windowFullscreen">true</item>
<item name="android:windowIsFloating">false</item> <item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">false</item> <item name="android:backgroundDimEnabled">false</item>
@ -29,4 +27,7 @@
<item name="android:windowEnterAnimation">@null</item> <item name="android:windowEnterAnimation">@null</item>
</style> </style>
<style name="TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="boxStrokeColor">@color/green_mc</item>
</style>
</resources> </resources>

View File

@ -16,10 +16,10 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.1.0' classpath 'com.android.tools.build:gradle:8.2.1'
//noinspection GradleDependency //noinspection GradleDependency
classpath 'de.undercouch:gradle-download-task:4.1.2' classpath 'de.undercouch:gradle-download-task:4.1.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.20' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }

View File

@ -1,6 +1,6 @@
#Mon Aug 21 21:17:06 EEST 2023 #Thu Oct 05 18:46:10 EEST 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -2,12 +2,12 @@ apply plugin: 'com.android.library'
apply plugin: 'de.undercouch.download' apply plugin: 'de.undercouch.download'
android { android {
compileSdkVersion 33 compileSdkVersion 34
buildToolsVersion '33.0.2' buildToolsVersion '34.0.0'
ndkVersion '25.2.9519653' ndkVersion '25.2.9519653'
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 34
externalNativeBuild { externalNativeBuild {
ndkBuild { ndkBuild {
arguments '-j' + Runtime.getRuntime().availableProcessors(), arguments '-j' + Runtime.getRuntime().availableProcessors(),
@ -50,17 +50,19 @@ android {
} }
// get precompiled deps // get precompiled deps
def buildDirectory = layout.buildDirectory.get().asFile
tasks.register('downloadDeps', Download) { tasks.register('downloadDeps', Download) {
def VERSION = "11082023" def VERSION = "05102023"
src "https://gitlab.com/minetest-stuffs/multicraft-deps_androit/-/archive/11082023/multicraft-deps_androit-11082023.zip" src "https://github.com/MultiCraft/deps_android/releases/download/$VERSION/deps_android.zip"
dest new File(buildDir, 'deps.zip') dest new File(buildDirectory, 'deps.zip')
overwrite false overwrite false
} }
tasks.register('getDeps', Copy) { tasks.register('getDeps', Copy) {
dependsOn downloadDeps dependsOn downloadDeps
def deps = file('deps') def deps = file('deps')
def f = file("$buildDir/deps_android") def f = file("$buildDirectory/deps_android")
if (!f.exists()) { if (!f.exists()) {
from zipTree(downloadDeps.dest) from zipTree(downloadDeps.dest)

View File

@ -122,7 +122,10 @@ LOCAL_C_INCLUDES := \
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
$(wildcard ../../src/client/*.cpp) \ $(wildcard ../../src/client/*.cpp) \
$(wildcard ../../src/client/*/*.cpp) \ ../../src/client/meshgen/collector.cpp \
../../src/client/render/core.cpp \
../../src/client/render/factory.cpp \
../../src/client/render/plain.cpp \
$(wildcard ../../src/content/*.cpp) \ $(wildcard ../../src/content/*.cpp) \
../../src/database/database.cpp \ ../../src/database/database.cpp \
../../src/database/database-dummy.cpp \ ../../src/database/database-dummy.cpp \

View File

@ -230,14 +230,9 @@
84F20E8D25D52868009562A9 /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E7A25D52868009562A9 /* base64.cpp */; }; 84F20E8D25D52868009562A9 /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E7A25D52868009562A9 /* base64.cpp */; };
84F20E8E25D52868009562A9 /* pointedthing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E7B25D52868009562A9 /* pointedthing.cpp */; }; 84F20E8E25D52868009562A9 /* pointedthing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E7B25D52868009562A9 /* pointedthing.cpp */; };
84F20E8F25D52868009562A9 /* directiontables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E7D25D52868009562A9 /* directiontables.cpp */; }; 84F20E8F25D52868009562A9 /* directiontables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E7D25D52868009562A9 /* directiontables.cpp */; };
84F20EA025D528C5009562A9 /* stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9025D528C4009562A9 /* stereo.cpp */; };
84F20EA125D528C5009562A9 /* core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9425D528C5009562A9 /* core.cpp */; }; 84F20EA125D528C5009562A9 /* core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9425D528C5009562A9 /* core.cpp */; };
84F20EA225D528C5009562A9 /* anaglyph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9625D528C5009562A9 /* anaglyph.cpp */; };
84F20EA325D528C5009562A9 /* plain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9725D528C5009562A9 /* plain.cpp */; }; 84F20EA325D528C5009562A9 /* plain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9725D528C5009562A9 /* plain.cpp */; };
84F20EA425D528C5009562A9 /* pageflip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9A25D528C5009562A9 /* pageflip.cpp */; };
84F20EA525D528C5009562A9 /* factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9B25D528C5009562A9 /* factory.cpp */; }; 84F20EA525D528C5009562A9 /* factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9B25D528C5009562A9 /* factory.cpp */; };
84F20EA625D528C5009562A9 /* sidebyside.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9C25D528C5009562A9 /* sidebyside.cpp */; };
84F20EA725D528C5009562A9 /* interlaced.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20E9E25D528C5009562A9 /* interlaced.cpp */; };
84F20EB025D528D7009562A9 /* subgames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20EA825D528D6009562A9 /* subgames.cpp */; }; 84F20EB025D528D7009562A9 /* subgames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20EA825D528D6009562A9 /* subgames.cpp */; };
84F20EB125D528D7009562A9 /* packages.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20EAD25D528D7009562A9 /* packages.cpp */; }; 84F20EB125D528D7009562A9 /* packages.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20EAD25D528D7009562A9 /* packages.cpp */; };
84F20EB225D528D7009562A9 /* mods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20EAE25D528D7009562A9 /* mods.cpp */; }; 84F20EB225D528D7009562A9 /* mods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F20EAE25D528D7009562A9 /* mods.cpp */; };
@ -380,7 +375,7 @@
84135B2225D5263A00CA4DCF /* texture_override.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = texture_override.h; path = ../../../src/texture_override.h; sourceTree = "<group>"; }; 84135B2225D5263A00CA4DCF /* texture_override.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = texture_override.h; path = ../../../src/texture_override.h; sourceTree = "<group>"; };
84135B2325D5263A00CA4DCF /* gettext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gettext.cpp; path = ../../../src/gettext.cpp; sourceTree = "<group>"; }; 84135B2325D5263A00CA4DCF /* gettext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gettext.cpp; path = ../../../src/gettext.cpp; sourceTree = "<group>"; };
84135B2425D5263A00CA4DCF /* metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = metadata.h; path = ../../../src/metadata.h; sourceTree = "<group>"; }; 84135B2425D5263A00CA4DCF /* metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = metadata.h; path = ../../../src/metadata.h; sourceTree = "<group>"; };
84135B2525D5263B00CA4DCF /* defaultsettings.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = defaultsettings.cpp; path = ../../../src/defaultsettings.cpp; sourceTree = "<group>"; }; 84135B2525D5263B00CA4DCF /* defaultsettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = defaultsettings.cpp; path = ../../../src/defaultsettings.cpp; sourceTree = "<group>"; };
84135B2625D5263B00CA4DCF /* mapnode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mapnode.h; path = ../../../src/mapnode.h; sourceTree = "<group>"; }; 84135B2625D5263B00CA4DCF /* mapnode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mapnode.h; path = ../../../src/mapnode.h; sourceTree = "<group>"; };
84135B2725D5263B00CA4DCF /* irr_aabb3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = irr_aabb3d.h; path = ../../../src/irr_aabb3d.h; sourceTree = "<group>"; }; 84135B2725D5263B00CA4DCF /* irr_aabb3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = irr_aabb3d.h; path = ../../../src/irr_aabb3d.h; sourceTree = "<group>"; };
84135B2825D5263C00CA4DCF /* craftdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = craftdef.h; path = ../../../src/craftdef.h; sourceTree = "<group>"; }; 84135B2825D5263C00CA4DCF /* craftdef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = craftdef.h; path = ../../../src/craftdef.h; sourceTree = "<group>"; };
@ -777,22 +772,12 @@
84F20E7D25D52868009562A9 /* directiontables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = directiontables.cpp; path = ../../../src/util/directiontables.cpp; sourceTree = "<group>"; }; 84F20E7D25D52868009562A9 /* directiontables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = directiontables.cpp; path = ../../../src/util/directiontables.cpp; sourceTree = "<group>"; };
84F20E7E25D52868009562A9 /* pointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pointer.h; path = ../../../src/util/pointer.h; sourceTree = "<group>"; }; 84F20E7E25D52868009562A9 /* pointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pointer.h; path = ../../../src/util/pointer.h; sourceTree = "<group>"; };
84F20E7F25D52868009562A9 /* quicktune.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quicktune.h; path = ../../../src/util/quicktune.h; sourceTree = "<group>"; }; 84F20E7F25D52868009562A9 /* quicktune.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quicktune.h; path = ../../../src/util/quicktune.h; sourceTree = "<group>"; };
84F20E9025D528C4009562A9 /* stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stereo.cpp; path = ../../../src/client/render/stereo.cpp; sourceTree = "<group>"; };
84F20E9125D528C4009562A9 /* sidebyside.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sidebyside.h; path = ../../../src/client/render/sidebyside.h; sourceTree = "<group>"; };
84F20E9225D528C5009562A9 /* factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = factory.h; path = ../../../src/client/render/factory.h; sourceTree = "<group>"; }; 84F20E9225D528C5009562A9 /* factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = factory.h; path = ../../../src/client/render/factory.h; sourceTree = "<group>"; };
84F20E9325D528C5009562A9 /* plain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plain.h; path = ../../../src/client/render/plain.h; sourceTree = "<group>"; }; 84F20E9325D528C5009562A9 /* plain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plain.h; path = ../../../src/client/render/plain.h; sourceTree = "<group>"; };
84F20E9425D528C5009562A9 /* core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = core.cpp; path = ../../../src/client/render/core.cpp; sourceTree = "<group>"; }; 84F20E9425D528C5009562A9 /* core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = core.cpp; path = ../../../src/client/render/core.cpp; sourceTree = "<group>"; };
84F20E9525D528C5009562A9 /* stereo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stereo.h; path = ../../../src/client/render/stereo.h; sourceTree = "<group>"; };
84F20E9625D528C5009562A9 /* anaglyph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = anaglyph.cpp; path = ../../../src/client/render/anaglyph.cpp; sourceTree = "<group>"; };
84F20E9725D528C5009562A9 /* plain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = plain.cpp; path = ../../../src/client/render/plain.cpp; sourceTree = "<group>"; }; 84F20E9725D528C5009562A9 /* plain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = plain.cpp; path = ../../../src/client/render/plain.cpp; sourceTree = "<group>"; };
84F20E9825D528C5009562A9 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../../../src/client/render/core.h; sourceTree = "<group>"; }; 84F20E9825D528C5009562A9 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../../../src/client/render/core.h; sourceTree = "<group>"; };
84F20E9925D528C5009562A9 /* anaglyph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = anaglyph.h; path = ../../../src/client/render/anaglyph.h; sourceTree = "<group>"; };
84F20E9A25D528C5009562A9 /* pageflip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pageflip.cpp; path = ../../../src/client/render/pageflip.cpp; sourceTree = "<group>"; };
84F20E9B25D528C5009562A9 /* factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = factory.cpp; path = ../../../src/client/render/factory.cpp; sourceTree = "<group>"; }; 84F20E9B25D528C5009562A9 /* factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = factory.cpp; path = ../../../src/client/render/factory.cpp; sourceTree = "<group>"; };
84F20E9C25D528C5009562A9 /* sidebyside.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sidebyside.cpp; path = ../../../src/client/render/sidebyside.cpp; sourceTree = "<group>"; };
84F20E9D25D528C5009562A9 /* pageflip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pageflip.h; path = ../../../src/client/render/pageflip.h; sourceTree = "<group>"; };
84F20E9E25D528C5009562A9 /* interlaced.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = interlaced.cpp; path = ../../../src/client/render/interlaced.cpp; sourceTree = "<group>"; };
84F20E9F25D528C5009562A9 /* interlaced.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = interlaced.h; path = ../../../src/client/render/interlaced.h; sourceTree = "<group>"; };
84F20EA825D528D6009562A9 /* subgames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = subgames.cpp; path = ../../../src/content/subgames.cpp; sourceTree = "<group>"; }; 84F20EA825D528D6009562A9 /* subgames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = subgames.cpp; path = ../../../src/content/subgames.cpp; sourceTree = "<group>"; };
84F20EA925D528D6009562A9 /* subgames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = subgames.h; path = ../../../src/content/subgames.h; sourceTree = "<group>"; }; 84F20EA925D528D6009562A9 /* subgames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = subgames.h; path = ../../../src/content/subgames.h; sourceTree = "<group>"; };
84F20EAA25D528D6009562A9 /* mods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mods.h; path = ../../../src/content/mods.h; sourceTree = "<group>"; }; 84F20EAA25D528D6009562A9 /* mods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mods.h; path = ../../../src/content/mods.h; sourceTree = "<group>"; };
@ -968,22 +953,12 @@
84135BA425D5269800CA4DCF /* render */ = { 84135BA425D5269800CA4DCF /* render */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
84F20E9625D528C5009562A9 /* anaglyph.cpp */,
84F20E9925D528C5009562A9 /* anaglyph.h */,
84F20E9425D528C5009562A9 /* core.cpp */, 84F20E9425D528C5009562A9 /* core.cpp */,
84F20E9825D528C5009562A9 /* core.h */, 84F20E9825D528C5009562A9 /* core.h */,
84F20E9B25D528C5009562A9 /* factory.cpp */, 84F20E9B25D528C5009562A9 /* factory.cpp */,
84F20E9225D528C5009562A9 /* factory.h */, 84F20E9225D528C5009562A9 /* factory.h */,
84F20E9E25D528C5009562A9 /* interlaced.cpp */,
84F20E9F25D528C5009562A9 /* interlaced.h */,
84F20E9A25D528C5009562A9 /* pageflip.cpp */,
84F20E9D25D528C5009562A9 /* pageflip.h */,
84F20E9725D528C5009562A9 /* plain.cpp */, 84F20E9725D528C5009562A9 /* plain.cpp */,
84F20E9325D528C5009562A9 /* plain.h */, 84F20E9325D528C5009562A9 /* plain.h */,
84F20E9C25D528C5009562A9 /* sidebyside.cpp */,
84F20E9125D528C4009562A9 /* sidebyside.h */,
84F20E9025D528C4009562A9 /* stereo.cpp */,
84F20E9525D528C5009562A9 /* stereo.h */,
); );
name = render; name = render;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1845,7 +1820,6 @@
84135B9E25D5264C00CA4DCF /* remoteplayer.cpp in Sources */, 84135B9E25D5264C00CA4DCF /* remoteplayer.cpp in Sources */,
84135C2025D526D700CA4DCF /* fontengine.cpp in Sources */, 84135C2025D526D700CA4DCF /* fontengine.cpp in Sources */,
84135B8425D5264C00CA4DCF /* chat.cpp in Sources */, 84135B8425D5264C00CA4DCF /* chat.cpp in Sources */,
84F20EA425D528C5009562A9 /* pageflip.cpp in Sources */,
84F20E8125D52868009562A9 /* string.cpp in Sources */, 84F20E8125D52868009562A9 /* string.cpp in Sources */,
84135C1E25D526D700CA4DCF /* clientobject.cpp in Sources */, 84135C1E25D526D700CA4DCF /* clientobject.cpp in Sources */,
84135B6B25D5264B00CA4DCF /* mapblock.cpp in Sources */, 84135B6B25D5264B00CA4DCF /* mapblock.cpp in Sources */,
@ -1870,7 +1844,6 @@
84F20DA325D527C5009562A9 /* socket.cpp in Sources */, 84F20DA325D527C5009562A9 /* socket.cpp in Sources */,
84135C1B25D526D700CA4DCF /* hud.cpp in Sources */, 84135C1B25D526D700CA4DCF /* hud.cpp in Sources */,
84F20DDD25D52812009562A9 /* s_inventory.cpp in Sources */, 84F20DDD25D52812009562A9 /* s_inventory.cpp in Sources */,
84F20EA225D528C5009562A9 /* anaglyph.cpp in Sources */,
84F20DB925D527D8009562A9 /* c_internal.cpp in Sources */, 84F20DB925D527D8009562A9 /* c_internal.cpp in Sources */,
84135B6E25D5264B00CA4DCF /* object_properties.cpp in Sources */, 84135B6E25D5264B00CA4DCF /* object_properties.cpp in Sources */,
84F20DAA25D527C5009562A9 /* networkpacket.cpp in Sources */, 84F20DAA25D527C5009562A9 /* networkpacket.cpp in Sources */,
@ -1928,7 +1901,6 @@
84135C2525D526D700CA4DCF /* imagefilters.cpp in Sources */, 84135C2525D526D700CA4DCF /* imagefilters.cpp in Sources */,
84135C1325D526D700CA4DCF /* clientlauncher.cpp in Sources */, 84135C1325D526D700CA4DCF /* clientlauncher.cpp in Sources */,
849D0848278AC1B200471354 /* chacha.c in Sources */, 849D0848278AC1B200471354 /* chacha.c in Sources */,
84F20EA025D528C5009562A9 /* stereo.cpp in Sources */,
84F20EB025D528D7009562A9 /* subgames.cpp in Sources */, 84F20EB025D528D7009562A9 /* subgames.cpp in Sources */,
84135B7825D5264B00CA4DCF /* clientiface.cpp in Sources */, 84135B7825D5264B00CA4DCF /* clientiface.cpp in Sources */,
84135C1725D526D700CA4DCF /* mesh.cpp in Sources */, 84135C1725D526D700CA4DCF /* mesh.cpp in Sources */,
@ -2014,7 +1986,6 @@
84F20F0E25D52958009562A9 /* modalMenu.cpp in Sources */, 84F20F0E25D52958009562A9 /* modalMenu.cpp in Sources */,
84F20E2E25D5282A009562A9 /* l_inventory.cpp in Sources */, 84F20E2E25D5282A009562A9 /* l_inventory.cpp in Sources */,
84135BA725D526A900CA4DCF /* collector.cpp in Sources */, 84135BA725D526A900CA4DCF /* collector.cpp in Sources */,
84F20EA725D528C5009562A9 /* interlaced.cpp in Sources */,
8458610724B13BDF0040BA4F /* mini-gmp.c in Sources */, 8458610724B13BDF0040BA4F /* mini-gmp.c in Sources */,
84F20F0A25D52958009562A9 /* guiBackgroundImage.cpp in Sources */, 84F20F0A25D52958009562A9 /* guiBackgroundImage.cpp in Sources */,
84F20DE325D52812009562A9 /* s_client.cpp in Sources */, 84F20DE325D52812009562A9 /* s_client.cpp in Sources */,
@ -2038,7 +2009,6 @@
84135B8225D5264C00CA4DCF /* server.cpp in Sources */, 84135B8225D5264C00CA4DCF /* server.cpp in Sources */,
84F20DDB25D52812009562A9 /* s_security.cpp in Sources */, 84F20DDB25D52812009562A9 /* s_security.cpp in Sources */,
84135B8825D5264C00CA4DCF /* gettext.cpp in Sources */, 84135B8825D5264C00CA4DCF /* gettext.cpp in Sources */,
84F20EA625D528C5009562A9 /* sidebyside.cpp in Sources */,
84F20E8325D52868009562A9 /* metricsbackend.cpp in Sources */, 84F20E8325D52868009562A9 /* metricsbackend.cpp in Sources */,
84135C2425D526D700CA4DCF /* content_mapblock.cpp in Sources */, 84135C2425D526D700CA4DCF /* content_mapblock.cpp in Sources */,
84E33D882A7BBEE900609F77 /* wrapper.m in Sources */, 84E33D882A7BBEE900609F77 /* wrapper.m in Sources */,
@ -2215,7 +2185,6 @@
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
"RUN_IN_PLACE=0", "RUN_IN_PLACE=0",
"USE_GETTEXT=1", "USE_GETTEXT=1",
"USE_CURL=1", "USE_CURL=1",
@ -2231,6 +2200,7 @@
"VERSION_EXTRA=\"\"", "VERSION_EXTRA=\"\"",
"DEVELOPMENT_BUILD=1", "DEVELOPMENT_BUILD=1",
); );
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"${SRCROOT}/../../src", "${SRCROOT}/../../src",
@ -2250,6 +2220,9 @@
"${SRCROOT}/../deps/libvorbis/include", "${SRCROOT}/../deps/libvorbis/include",
); );
INFOPLIST_FILE = MultiCraft/Info.plist; INFOPLIST_FILE = MultiCraft/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.adventure-games";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Minetest.org. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 2.0.5; MARKETING_VERSION = 2.0.5;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
@ -2285,7 +2258,6 @@
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
"NDEBUG=1", "NDEBUG=1",
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
"RUN_IN_PLACE=0", "RUN_IN_PLACE=0",
"USE_GETTEXT=1", "USE_GETTEXT=1",
"USE_CURL=1", "USE_CURL=1",
@ -2301,6 +2273,7 @@
"VERSION_EXTRA=\"\"", "VERSION_EXTRA=\"\"",
"DEVELOPMENT_BUILD=0", "DEVELOPMENT_BUILD=0",
); );
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"${SRCROOT}/../../src", "${SRCROOT}/../../src",
@ -2320,6 +2293,9 @@
"${SRCROOT}/../deps/libvorbis/include", "${SRCROOT}/../deps/libvorbis/include",
); );
INFOPLIST_FILE = MultiCraft/Info.plist; INFOPLIST_FILE = MultiCraft/Info.plist;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.adventure-games";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 MultiCraft Studio OÜ. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 2.0.5; MARKETING_VERSION = 2.0.5;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 KiB

After

Width:  |  Height:  |  Size: 653 KiB

View File

@ -22,18 +22,10 @@
<string>$(CURRENT_PROJECT_VERSION)</string> <string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.adventure-games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2023 MultiCraft Studio OÜ. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticTermination</key>
<true/>
<key>NSSupportsSuddenTermination</key> <key>NSSupportsSuddenTermination</key>
<true/> <true/>
</dict> </dict>

View File

@ -6,6 +6,8 @@ extern "C" {
const char *get_secret_key(const char *key); const char *get_secret_key(const char *key);
float get_screen_scale();
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,3 +1,4 @@
@import AppKit;
@import Foundation; @import Foundation;
#import "wrapper.h" #import "wrapper.h"
@ -6,3 +7,8 @@ const char *get_secret_key(const char *key)
{ {
return "dummy"; return "dummy";
} }
float get_screen_scale()
{
return [NSScreen mainScreen].backingScaleFactor;
}

View File

@ -1,6 +1,6 @@
#!/bin/bash -e #!/bin/bash -e
SDL2_VERSION=release-2.28.3 SDL2_VERSION=release-2.28.4
. scripts/sdk.sh . scripts/sdk.sh
mkdir -p deps; cd deps mkdir -p deps; cd deps

View File

@ -1,6 +1,6 @@
#!/bin/bash -e #!/bin/bash -e
GETTEXT_VERSION=0.22 GETTEXT_VERSION=0.22.3
. scripts/sdk.sh . scripts/sdk.sh
mkdir -p deps; cd deps mkdir -p deps; cd deps

View File

@ -1,15 +1,13 @@
#!/bin/bash -e #!/bin/bash -e
JPEG_VERSION=3.0.0 JPEG_VERSION=3.0.1
. scripts/sdk.sh . scripts/sdk.sh
mkdir -p deps; cd deps mkdir -p deps; cd deps
if [ ! -d libjpeg-src ]; then if [ ! -d libjpeg-src ]; then
wget https://download.sourceforge.net/libjpeg-turbo/libjpeg-turbo-$JPEG_VERSION.tar.gz git clone -b $JPEG_VERSION --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo libjpeg-src
tar -xzf libjpeg-turbo-$JPEG_VERSION.tar.gz mkdir libjpeg-src/build
mv libjpeg-turbo-$JPEG_VERSION libjpeg-src
rm libjpeg-turbo-$JPEG_VERSION.tar.gz
fi fi
rm -rf libjpeg rm -rf libjpeg

View File

@ -6,10 +6,15 @@ if [ ! -d MultiCraft/MultiCraft.xcodeproj ]; then
fi fi
DEST=$(pwd)/assets/locale DEST=$(pwd)/assets/locale
broken_langs=(fil gd gl dv eo he hi jbo kn ko kk ky ms_Arab nn pt_BR sr_Cyrl sr_Latn zh_CN zh_TW)
pushd ../po pushd ../po
for lang in *; do for lang in *; do
[ ${#lang} -ne 2 ] && continue [ ${#lang} -ne 2 ] && continue
# Skip broken languages
if [[ " ${broken_langs[@]} " =~ " ${lang} " ]]; then
continue
fi
mopath=$DEST/$lang/LC_MESSAGES mopath=$DEST/$lang/LC_MESSAGES
mkdir -p $mopath mkdir -p $mopath
pushd $lang pushd $lang
@ -21,9 +26,5 @@ for lang in *; do
done done
popd popd
# Remove hidden files and directories
find $DEST -type d,f -name '.*' -print0 | xargs -0 -- rm -rf find $DEST -type d,f -name '.*' -print0 | xargs -0 -- rm -rf
# remove broken languages
for broken_lang in dv eo he hi kn ko ms_Arab nn pt_BR sr_* zh_*; do
rm -rf $DEST/$broken_lang
done

View File

@ -562,8 +562,7 @@ function store.load()
end end
end end
local timeout = tonumber(core.settings:get("curl_file_download_timeout")) local response = http.fetch_sync({ url = url })
local response = http.fetch_sync({ url = url, timeout = timeout })
if not response.succeeded then if not response.succeeded then
return return
end end

View File

@ -104,14 +104,19 @@ function menudata.init_tabs()
tab_name_selected = "content", tab_name_selected = "content",
is_open_cdb = true, is_open_cdb = true,
on_click = function(this) on_click = function(this)
if #pkgmgr.games > 1 or (pkgmgr.games[1] and pkgmgr.games[1].id ~= "default") then -- Show the content tab if no hidden games are installed
this:set_tab("content") for _, game in ipairs(pkgmgr.games) do
else if not game.hidden then
local dialog = create_store_dlg() this:set_tab("content")
dialog:set_parent(this) return
this:hide() end
dialog:show()
end end
-- Otherwise open the store dialog
local dialog = create_store_dlg("game")
dialog:set_parent(this)
this:hide()
dialog:show()
end, end,
}) })

View File

@ -908,6 +908,7 @@ function pkgmgr.update_gamelist()
-- Update default_game_idx -- Update default_game_idx
for i, game in ipairs(pkgmgr.games) do for i, game in ipairs(pkgmgr.games) do
if game.id == "default" then if game.id == "default" then
-- Used by tab_local
pkgmgr.default_game_idx = i pkgmgr.default_game_idx = i
break break
end end

View File

@ -32,7 +32,7 @@ local function get_formspec(tabview, name, tabdata)
packages_raw = {} packages_raw = {}
local i = 0 local i = 0
for _, game in ipairs(pkgmgr.games) do for _, game in ipairs(pkgmgr.games) do
if game.id ~= "default" then if not game.hidden then
i = i + 1 i = i + 1
packages_raw[i] = game packages_raw[i] = game
end end

View File

@ -741,7 +741,7 @@ crosshair_alpha (Crosshair alpha) int 255 0 255
recent_chat_messages (Recent Chat Messages) int 6 2 20 recent_chat_messages (Recent Chat Messages) int 6 2 20
# Whether node texture animations should be desynchronized per mapblock. # Whether node texture animations should be desynchronized per mapblock.
desynchronize_mapblock_texture_animation (Desynchronize block animation) bool true desynchronize_mapblock_texture_animation (Desynchronize block animation) bool false
# Maximum proportion of current window to be used for hotbar. # Maximum proportion of current window to be used for hotbar.
# Useful if there's something to be displayed right or left of hotbar. # Useful if there's something to be displayed right or left of hotbar.
@ -1352,6 +1352,7 @@ server_side_occlusion_culling (Server side occlusion culling) bool true
# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to # LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to
# csm_restriction_noderange) # csm_restriction_noderange)
# READ_PLAYERINFO: 32 (disable get_player_names call client-side) # READ_PLAYERINFO: 32 (disable get_player_names call client-side)
# THIRD_PARTY_MODS: 256 (disable loading third-party CSMs)
csm_restriction_flags (Client side modding restrictions) int 62 csm_restriction_flags (Client side modding restrictions) int 62
# If the CSM restriction for node range is enabled, get_node calls are limited # If the CSM restriction for node range is enabled, get_node calls are limited

View File

@ -861,7 +861,7 @@
# Whether node texture animations should be desynchronized per mapblock. # Whether node texture animations should be desynchronized per mapblock.
# type: bool # type: bool
# desynchronize_mapblock_texture_animation = true # desynchronize_mapblock_texture_animation = false
# Maximum proportion of current window to be used for hotbar. # Maximum proportion of current window to be used for hotbar.
# Useful if there's something to be displayed right or left of hotbar. # Useful if there's something to be displayed right or left of hotbar.
@ -1611,6 +1611,7 @@
# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to # LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to
# csm_restriction_noderange) # csm_restriction_noderange)
# READ_PLAYERINFO: 32 (disable get_player_names call client-side) # READ_PLAYERINFO: 32 (disable get_player_names call client-side)
# THIRD_PARTY_MODS: 256 (disable loading third-party client-provided mods)
# type: int # type: int
# csm_restriction_flags = 60 # csm_restriction_flags = 60

View File

@ -164,33 +164,35 @@ void Client::loadMods()
scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath());
m_script->loadModFromMemory(BUILTIN_MOD_NAME); m_script->loadModFromMemory(BUILTIN_MOD_NAME);
ClientModConfiguration modconf(getClientModsLuaPath()); if (!checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_THIRD_PARTY_MODS)) {
m_mods = modconf.getMods(); ClientModConfiguration modconf(getClientModsLuaPath());
// complain about mods with unsatisfied dependencies m_mods = modconf.getMods();
if (!modconf.isConsistent()) { // complain about mods with unsatisfied dependencies
modconf.printUnsatisfiedModsError(); if (!modconf.isConsistent()) {
return; modconf.printUnsatisfiedModsError();
} return;
// Print mods
infostream << "Client loading mods: ";
for (const ModSpec &mod : m_mods)
infostream << mod.name << " ";
infostream << std::endl;
// Load "mod" scripts
for (const ModSpec &mod : m_mods) {
if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) {
throw ModError("Error loading mod \"" + mod.name +
"\": Mod name does not follow naming conventions: "
"Only characters [a-z0-9_] are allowed.");
} }
scanModIntoMemory(mod.name, mod.path);
}
// Run them // Print mods
for (const ModSpec &mod : m_mods) infostream << "Client loading mods: ";
m_script->loadModFromMemory(mod.name); for (const ModSpec &mod : m_mods)
infostream << mod.name << " ";
infostream << std::endl;
// Load "mod" scripts
for (const ModSpec &mod : m_mods) {
if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) {
throw ModError("Error loading mod \"" + mod.name +
"\": Mod name does not follow naming conventions: "
"Only characters [a-z0-9_] are allowed.");
}
scanModIntoMemory(mod.name, mod.path);
}
// Run them
for (const ModSpec &mod : m_mods)
m_script->loadModFromMemory(mod.name);
}
// Mods are done loading. Unlock callbacks // Mods are done loading. Unlock callbacks
m_mods_loaded = true; m_mods_loaded = true;

View File

@ -1420,10 +1420,15 @@ void MapblockMeshGenerator::drawMeshNode()
// Convert wallmounted to 6dfacedir. // Convert wallmounted to 6dfacedir.
// When cache enabled, it is already converted. // When cache enabled, it is already converted.
facedir = n.getWallMounted(nodedef); facedir = n.getWallMounted(nodedef);
if (!enable_mesh_cache) if (!enable_mesh_cache) {
facedir = wallmounted_to_facedir[facedir]; facedir = wallmountedToFacedir(facedir);
}
} }
// f->mesh_ptr has 24 elements
if (facedir > 23)
facedir = 0;
if (!data->m_smooth_lighting && f->mesh_ptr[facedir]) { if (!data->m_smooth_lighting && f->mesh_ptr[facedir]) {
// use cached meshes // use cached meshes
private_mesh = false; private_mesh = false;

View File

@ -1530,6 +1530,8 @@ bool Game::connectToServer(const GameStartData &start_data,
Wait for server to accept connection Wait for server to accept connection
*/ */
bool result = true;
try { try {
input->clear(); input->clear();
@ -1539,7 +1541,7 @@ bool Game::connectToServer(const GameStartData &start_data,
fps_control.last_time = RenderingEngine::get_timer_time(); fps_control.last_time = RenderingEngine::get_timer_time();
while (RenderingEngine::run()) { while ((result = RenderingEngine::run())) {
limitFps(&fps_control, &dtime); limitFps(&fps_control, &dtime);
@ -1603,7 +1605,7 @@ bool Game::connectToServer(const GameStartData &start_data,
return false; return false;
} }
return true; return result;
} }
bool Game::getServerContent(bool *aborted) bool Game::getServerContent(bool *aborted)
@ -1615,7 +1617,8 @@ bool Game::getServerContent(bool *aborted)
fps_control.last_time = RenderingEngine::get_timer_time(); fps_control.last_time = RenderingEngine::get_timer_time();
while (RenderingEngine::run()) { bool result = true;
while ((result = RenderingEngine::run())) {
limitFps(&fps_control, &dtime); limitFps(&fps_control, &dtime);
@ -1691,7 +1694,7 @@ bool Game::getServerContent(bool *aborted)
} }
} }
return true; return result;
} }

View File

@ -74,14 +74,14 @@ void GameUI::init(Client *client)
// At the middle of the screen // At the middle of the screen
// Object infos are shown in this // Object infos are shown in this
u32 chat_font_height = m_guitext_chat->getActiveFont()->getDimension(L"Ay").Height; u32 chat_font_height = m_guitext_chat->getActiveFont()->getDimension(L"Ay").Height;
float scale = 1.0f; v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();
#if defined(__ANDROID__) || defined(__APPLE__) s32 text_height = g_fontengine->getTextHeight() * 6;
scale = RenderingEngine::getDisplayDensity() * client->getHudScaling() * 0.5f; s32 top_y = (screensize.Y - text_height) / 2;
#endif s32 horiz_offset = 100 + client->getRoundScreen();
m_guitext_info = gui::StaticText::add(guienv, L"", m_guitext_info = gui::StaticText::add(guienv, L"",
core::rect<s32>(0, 0, 400, g_fontengine->getTextHeight() * 6) + core::rect<s32>(horiz_offset, top_y,
v2s32(100 + client->getRoundScreen(), horiz_offset + 400, top_y + text_height),
chat_font_height * (g_settings->getU16("recent_chat_messages") + 3) * scale),
false, true, guiroot); false, true, guiroot);
// Status text (displays info when showing and hiding GUI stuff, etc.) // Status text (displays info when showing and hiding GUI stuff, etc.)

View File

@ -194,7 +194,6 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
#ifdef __IOS__ #ifdef __IOS__
} else if (event.EventType == irr::EET_APPLICATION_EVENT) { } else if (event.EventType == irr::EET_APPLICATION_EVENT) {
int AppEvent = event.ApplicationEvent.EventType; int AppEvent = event.ApplicationEvent.EventType;
ioswrap_events(AppEvent);
if (AppEvent == irr::EAET_WILL_PAUSE) if (AppEvent == irr::EAET_WILL_PAUSE)
external_pause_game(); external_pause_game();
return true; return true;

View File

@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "anaglyph.h" #include "anaglyph.h"
#include <irrlicht.h>
void RenderingCoreAnaglyph::drawAll() void RenderingCoreAnaglyph::drawAll()
{ {
renderBothImages(); renderBothImages();

View File

@ -31,6 +31,7 @@ RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevic
{ {
if (stereo_mode == "none") if (stereo_mode == "none")
return new RenderingCorePlain(device, client, hud); return new RenderingCorePlain(device, client, hud);
#if !defined(__ANDROID__) && !defined(__APPLE__)
if (stereo_mode == "anaglyph") if (stereo_mode == "anaglyph")
return new RenderingCoreAnaglyph(device, client, hud); return new RenderingCoreAnaglyph(device, client, hud);
if (stereo_mode == "interlaced") if (stereo_mode == "interlaced")
@ -45,6 +46,7 @@ RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevic
return new RenderingCoreSideBySide(device, client, hud, true); return new RenderingCoreSideBySide(device, client, hud, true);
if (stereo_mode == "crossview") if (stereo_mode == "crossview")
return new RenderingCoreSideBySide(device, client, hud, false, true); return new RenderingCoreSideBySide(device, client, hud, false, true);
#endif
// fallback to plain renderer // fallback to plain renderer
errorstream << "Invalid rendering mode: " << stereo_mode << std::endl; errorstream << "Invalid rendering mode: " << stereo_mode << std::endl;

View File

@ -781,7 +781,7 @@ v2u32 RenderingEngine::getDisplaySize()
#else // __ANDROID__/__IOS__ #else // __ANDROID__/__IOS__
float RenderingEngine::getDisplayDensity() float RenderingEngine::getDisplayDensity()
{ {
static const float density = porting::getDisplayDensity(); static const float density = porting::getScreenScale();
return density; return density;
} }

View File

@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "config.h" #include "config.h"
#include "metadata.h" #include "metadata.h"
#define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_" #define MODNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789-_"
struct ModSpec struct ModSpec
{ {

View File

@ -144,13 +144,17 @@ SubgameSpec findSubgame(const std::string &id)
if (conf.exists("moddable")) if (conf.exists("moddable"))
moddable = conf.getBool("moddable"); moddable = conf.getBool("moddable");
bool hide_game = false;
if (conf.exists("hide_game"))
hide_game = conf.getBool("hide_game");
std::string menuicon_path; std::string menuicon_path;
#ifndef SERVER #ifndef SERVER
menuicon_path = getImagePath( menuicon_path = getImagePath(
game_path + DIR_DELIM + "menu" + DIR_DELIM + "icon.png"); game_path + DIR_DELIM + "menu" + DIR_DELIM + "icon.png");
#endif #endif
return SubgameSpec(id, game_path, gamemod_path, mods_paths, game_name, return SubgameSpec(id, game_path, gamemod_path, mods_paths, game_name,
menuicon_path, game_author, game_release, moddable); menuicon_path, game_author, game_release, moddable, hide_game);
} }
SubgameSpec findWorldSubgame(const std::string &world_path) SubgameSpec findWorldSubgame(const std::string &world_path)

View File

@ -36,6 +36,7 @@ struct SubgameSpec
std::set<std::string> addon_mods_paths; std::set<std::string> addon_mods_paths;
std::string menuicon_path; std::string menuicon_path;
bool moddable; bool moddable;
bool hidden;
SubgameSpec(const std::string &id = "", const std::string &path = "", SubgameSpec(const std::string &id = "", const std::string &path = "",
const std::string &gamemods_path = "", const std::string &gamemods_path = "",
@ -44,11 +45,11 @@ struct SubgameSpec
const std::string &name = "", const std::string &name = "",
const std::string &menuicon_path = "", const std::string &menuicon_path = "",
const std::string &author = "", int release = 0, const std::string &author = "", int release = 0,
const bool moddable = true) : const bool moddable = true, const bool hidden = false) :
id(id), id(id),
name(name), author(author), release(release), path(path), name(name), author(author), release(release), path(path),
gamemods_path(gamemods_path), addon_mods_paths(addon_mods_paths), gamemods_path(gamemods_path), addon_mods_paths(addon_mods_paths),
menuicon_path(menuicon_path), moddable(moddable) menuicon_path(menuicon_path), moddable(moddable), hidden(hidden)
{ {
} }

View File

@ -30,12 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/renderingengine.h" #include "client/renderingengine.h"
#endif #endif
#ifdef __APPLE__
#ifdef __IOS__ #ifdef __IOS__
#import "SDVersion.h" #import "wrapper.h"
#else
#import <AppKit/AppKit.h>
#endif
#endif #endif
void set_default_settings() void set_default_settings()
@ -240,7 +236,7 @@ void set_default_settings()
settings->setDefault("gui_scaling", "1.0"); settings->setDefault("gui_scaling", "1.0");
settings->setDefault("gui_scaling_filter", "false"); settings->setDefault("gui_scaling_filter", "false");
settings->setDefault("gui_scaling_filter_txr2img", "true"); settings->setDefault("gui_scaling_filter_txr2img", "true");
settings->setDefault("desynchronize_mapblock_texture_animation", "true"); settings->setDefault("desynchronize_mapblock_texture_animation", "false");
settings->setDefault("hud_hotbar_max_width", "1.0"); settings->setDefault("hud_hotbar_max_width", "1.0");
settings->setDefault("hud_move_upwards", "0"); settings->setDefault("hud_move_upwards", "0");
settings->setDefault("round_screen", "0"); settings->setDefault("round_screen", "0");
@ -507,7 +503,7 @@ void set_default_settings()
settings->setDefault("keymap_camera_mode", "KEY_KEY_C"); settings->setDefault("keymap_camera_mode", "KEY_KEY_C");
settings->setDefault("vsync", "true"); settings->setDefault("vsync", "true");
int ScaleFactor = (int) [NSScreen mainScreen].backingScaleFactor; int ScaleFactor = porting::getScreenScale();
settings->setDefault("screen_dpi", std::to_string(ScaleFactor * 72)); settings->setDefault("screen_dpi", std::to_string(ScaleFactor * 72));
if (ScaleFactor >= 2) { if (ScaleFactor >= 2) {
settings->setDefault("hud_scaling", "1.5"); settings->setDefault("hud_scaling", "1.5");
@ -616,7 +612,7 @@ void set_default_settings()
} else { } else {
// high settings // high settings
settings->setDefault("client_mapblock_limit", "500"); settings->setDefault("client_mapblock_limit", "500");
settings->setDefault("viewing_range", "125"); settings->setDefault("viewing_range", "120");
settings->setDefault("active_object_send_range_blocks", "4"); settings->setDefault("active_object_send_range_blocks", "4");
settings->setDefault("max_block_generate_distance", "5"); settings->setDefault("max_block_generate_distance", "5");

View File

@ -215,26 +215,26 @@ public:
private: private:
CurlHandlePool *pool; CurlHandlePool *pool;
CURL *curl; CURL *curl = nullptr;
CURLM *multi; CURLM *multi = nullptr;
HTTPFetchRequest request; HTTPFetchRequest request;
HTTPFetchResult result; HTTPFetchResult result;
std::ostringstream oss; std::ostringstream oss;
struct curl_slist *http_header; struct curl_slist *http_header = nullptr;
curl_httppost *post; #if LIBCURL_VERSION_NUM >= 0x075500
curl_mime *multipart_mime = nullptr;
#elif LIBCURL_VERSION_NUM >= 0x071304
curl_httppost *post = nullptr;
#endif
}; };
HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
CurlHandlePool *pool_): CurlHandlePool *pool_):
pool(pool_), pool(pool_),
curl(NULL),
multi(NULL),
request(request_), request(request_),
result(request_), result(request_),
oss(std::ios::binary), oss(std::ios::binary)
http_header(NULL),
post(NULL)
{ {
curl = pool->alloc(); curl = pool->alloc();
if (curl == NULL) { if (curl == NULL) {
@ -257,15 +257,16 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
} }
#if LIBCURL_VERSION_NUM >= 0x071304
// Restrict protocols so that curl vulnerabilities in // Restrict protocols so that curl vulnerabilities in
// other protocols don't affect us. // other protocols don't affect us.
// These settings were introduced in curl 7.19.4. #if LIBCURL_VERSION_NUM >= 0x075500
long protocols = // These settings were introduced in curl 7.85.0.
CURLPROTO_HTTP | const char *protocols = "HTTP,HTTPS,FTP,FTPS";
CURLPROTO_HTTPS | curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, protocols);
CURLPROTO_FTP | curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, protocols);
CURLPROTO_FTPS; #elif LIBCURL_VERSION_NUM >= 0x071304
// These settings were introduced in curl 7.19.4, and later deprecated.
long protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | CURLPROTO_FTPS;
curl_easy_setopt(curl, CURLOPT_PROTOCOLS, protocols); curl_easy_setopt(curl, CURLOPT_PROTOCOLS, protocols);
curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, protocols); curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, protocols);
#endif #endif
@ -296,6 +297,15 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
// Set data from fields or raw_data // Set data from fields or raw_data
if (request.multipart) { if (request.multipart) {
#if LIBCURL_VERSION_NUM >= 0x075500
multipart_mime = curl_mime_init(curl);
for (auto &it : request.fields) {
curl_mimepart *part = curl_mime_addpart(multipart_mime);
curl_mime_name(part, it.first.c_str());
curl_mime_data(part, it.second.c_str(), it.second.size());
}
curl_easy_setopt(curl, CURLOPT_MIMEPOST, multipart_mime);
#elif LIBCURL_VERSION_NUM >= 0x071304
curl_httppost *last = NULL; curl_httppost *last = NULL;
for (StringMap::iterator it = request.fields.begin(); for (StringMap::iterator it = request.fields.begin();
it != request.fields.end(); ++it) { it != request.fields.end(); ++it) {
@ -307,8 +317,8 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
CURLFORM_END); CURLFORM_END);
} }
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
// request.post_fields must now *never* be // request.post_fields must now *never* be modified until CURLOPT_HTTPPOST is cleared
// modified until CURLOPT_HTTPPOST is cleared #endif
} else { } else {
switch (request.method) { switch (request.method) {
case HTTP_GET: case HTTP_GET:
@ -423,11 +433,17 @@ HTTPFetchOngoing::~HTTPFetchOngoing()
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL);
curl_slist_free_all(http_header); curl_slist_free_all(http_header);
} }
#if LIBCURL_VERSION_NUM >= 0x075500
if (multipart_mime) {
curl_easy_setopt(curl, CURLOPT_MIMEPOST, nullptr);
curl_mime_free(multipart_mime);
}
#elif LIBCURL_VERSION_NUM >= 0x071304
if (post) { if (post) {
curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL); curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL);
curl_formfree(post); curl_formfree(post);
} }
#endif
// Store the cURL handle for reuse // Store the cURL handle for reuse
pool->free(curl); pool->free(curl);
} }

View File

@ -3857,38 +3857,5 @@ inline std::wostream& operator<<(std::wostream& out, const ustring16<TAlloc>& in
} }
#endif #endif
#ifndef USTRING_NO_STL
namespace unicode
{
//! Hashing algorithm for hashing a ustring. Used for things like unordered_maps.
//! Algorithm taken from std::hash<std::string>.
class hash : public std::unary_function<core::ustring, size_t>
{
public:
size_t operator()(const core::ustring& s) const
{
size_t ret = 2166136261U;
size_t index = 0;
size_t stride = 1 + s.size_raw() / 10;
core::ustring::const_iterator i = s.begin();
while (i != s.end())
{
// TODO: Don't force u32 on an x64 OS. Make it agnostic.
ret = 16777619U * ret ^ (size_t)s[(u32)index];
index += stride;
i += stride;
}
return (ret);
}
};
} // end namespace unicode
#endif
} // end namespace core } // end namespace core
} // end namespace irr } // end namespace irr

View File

@ -53,6 +53,20 @@ MapgenV7P::MapgenV7P(MapgenV7PParams *params, EmergeParams *emerge)
{ {
spflags = params->spflags; spflags = params->spflags;
// Initialise some values to hardcoded defaults
cave_width = 0.09;
large_cave_depth = -33;
small_cave_num_min = 0;
small_cave_num_max = 0;
large_cave_num_min = 0;
large_cave_num_max = 2;
large_cave_flooded = 0.5;
cavern_limit = -256;
cavern_taper = 256;
cavern_threshold = 0.7;
dungeon_ymin = -31000;
dungeon_ymax = 31000;
// Average of mgv6 small caves count // Average of mgv6 small caves count
small_caves_count = 6 * csize.X * csize.Z * MAP_BLOCKSIZE / 50000; small_caves_count = 6 * csize.X * csize.Z * MAP_BLOCKSIZE / 50000;
@ -76,6 +90,13 @@ MapgenV7P::MapgenV7P(MapgenV7PParams *params, EmergeParams *emerge)
noise_ridge = new Noise(&params->np_ridge, seed, csize.X, csize.Z); noise_ridge = new Noise(&params->np_ridge, seed, csize.X, csize.Z);
} }
// 3D noise, 1 down overgeneration
MapgenBasic::np_cave1 = NoiseParams(0.0, 12.0, v3f(61.0, 61.0, 61.0), 52534, 3, 0.5, 2.0);
MapgenBasic::np_cave2 = NoiseParams(0.0, 12.0, v3f(67.0, 67.0, 67.0), 10325, 3, 0.5, 2.0);
MapgenBasic::np_cavern = NoiseParams(0.0, 1.0, v3f(384.0, 128.0, 384.0), 723, 5, 0.63, 2.0);
// 3D noise
MapgenBasic::np_dungeons = NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0);
// Resolve additional nodes // Resolve additional nodes
c_bedrock = ndef->getId("mapgen_bedrock"); c_bedrock = ndef->getId("mapgen_bedrock");
} }

View File

@ -151,7 +151,7 @@ u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
return (getParam2() & 0x1F) % 24; return (getParam2() & 0x1F) % 24;
if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED || if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED ||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) f.param_type_2 == CPT2_COLORED_WALLMOUNTED))
return wallmounted_to_facedir[getParam2() & 0x07]; return wallmountedToFacedir(getParam2() & 0x07);
return 0; return 0;
} }

View File

@ -1051,6 +1051,7 @@ enum CSMRestrictionFlags : u64 {
CSM_RF_READ_NODEDEFS = 0x00000008, // Disable nodedef lookups CSM_RF_READ_NODEDEFS = 0x00000008, // Disable nodedef lookups
CSM_RF_LOOKUP_NODES = 0x00000010, // Limit node lookups CSM_RF_LOOKUP_NODES = 0x00000010, // Limit node lookups
CSM_RF_READ_PLAYERINFO = 0x00000020, // Disable player info lookups CSM_RF_READ_PLAYERINFO = 0x00000020, // Disable player info lookups
CSM_RF_THIRD_PARTY_MODS = 0x00000100, // Don't load third-party CSMs
CSM_RF_ALL = 0xFFFFFFFF, CSM_RF_ALL = 0xFFFFFFFF,
}; };

View File

@ -751,6 +751,12 @@ std::string getSecretKey(const std::string &key)
{ {
return std::string(get_secret_key(key.c_str())); return std::string(get_secret_key(key.c_str()));
} }
float getScreenScale()
{
static const float retval = get_screen_scale();
return retval;
}
#endif #endif
float getTotalSystemMemory() float getTotalSystemMemory()

View File

@ -360,6 +360,8 @@ bool open_url(const std::string &url);
#if defined(__APPLE__) #if defined(__APPLE__)
std::string getSecretKey(const std::string &key); std::string getSecretKey(const std::string &key);
float getScreenScale();
#endif #endif
/** /**

View File

@ -328,8 +328,7 @@ void notifyExitGame()
jnienv->ExceptionClear(); jnienv->ExceptionClear();
} }
#ifndef SERVER float getScreenScale()
float getDisplayDensity()
{ {
static bool firstRun = true; static bool firstRun = true;
static float value = 0; static float value = 0;
@ -347,7 +346,6 @@ float getDisplayDensity()
return value; return value;
} }
#endif // ndef SERVER
void finishGame(const std::string &exc) void finishGame(const std::string &exc)
{ {

View File

@ -82,9 +82,10 @@ void notifyServerConnect(bool is_multiplayer);
*/ */
void notifyExitGame(); void notifyExitGame();
#ifndef SERVER /**
float getDisplayDensity(); * get screen density
#endif */
float getScreenScale();
/** /**
* call Android function to finish * call Android function to finish

Some files were not shown because too many files have changed in this diff Show More