Compare commits

...

25 Commits

Author SHA1 Message Date
Kain344 93dd08049c chore: add firefly-go library, versioning assets, and release configuration files
Build / build (push) Successful in 5m39s
2026-06-15 19:05:27 +07:00
Kain344 8c1b105942 feat: fix bug
Build / build (push) Successful in 5m3s
2026-06-10 10:23:04 +07:00
Kain344 ee390c249a feat: fix bug
Build / build (push) Successful in 10m28s
2026-06-10 10:13:47 +07:00
Kain344 55ab8136f3 feat: update version to 4.3.2-01 and changelog
Build / build (push) Successful in 5m13s
2026-06-09 19:32:34 +07:00
Kain344 dd2f98c809 feat: optimaze
Build / build (push) Successful in 5m41s
2026-06-07 13:20:59 +07:00
Kain344 08ee73b2eb feat: update data
Build / build (push) Successful in 5m32s
2026-06-04 08:39:19 +07:00
Kain344 3b1f235e81 feat: update data
Build / build (push) Has been cancelled
2026-06-04 08:35:14 +07:00
Kain344 87f9c17352 UPDATE: 4.2.0
Build / build (push) Successful in 5m10s
2026-04-22 08:32:05 +07:00
Kain344 79776ddb45 UPDATE: new data
Build / build (push) Successful in 5m15s
2026-04-16 11:29:55 +07:00
Kain344 e398ead7ba UPDATE: Support custom lineup
Build / build (push) Successful in 5m32s
2026-04-12 17:16:00 +07:00
Kain344 f6938e8b8a FIX: fix stuck when replace lineup
Build / build (push) Successful in 5m22s
2026-04-07 20:46:46 +07:00
Kain344 a2eb9d37f6 UPDATE: v4
Build / build (push) Successful in 10m49s
2026-04-07 16:23:40 +07:00
Kain344 a99eb85fdd UPDATE: Real map fix
Build / build (push) Successful in 5m24s
2026-04-04 00:11:40 +07:00
Kain344 bd647edd48 UPDATE: Fix bug
Build / build (push) Successful in 5m18s
2026-04-03 18:01:15 +07:00
Kain344 77374d8b50 UPDATE: Fix bug 2026-04-03 18:00:54 +07:00
Kain344 a6be76cc3a UPDATE: Fix load map
Build / build (push) Successful in 5m18s
2026-04-02 01:09:45 +07:00
Kain344 8c56999da0 UPDATE: New data
Build / build (push) Successful in 5m40s
2026-03-31 12:38:21 +07:00
Kain344 898b0b9235 UPDATE: Fix something
Build / build (push) Successful in 5m49s
2026-03-29 12:38:39 +07:00
Kain344 2d74e99b32 UPDATE: 4.1.5X
Build / build (push) Successful in 5m56s
2026-03-20 02:51:29 +07:00
Kain344 988eeb2dd9 UPDATE: 4.0.5X
Build / build (push) Successful in 10m25s
2026-03-16 16:51:31 +07:00
Kain344 f64f690a0a UPDATE: 3.7.52
Build / build (push) Successful in 13m0s
2025-11-11 21:04:25 +07:00
Kain344 b0c4a7e05a UPDATE: Support TCP, Apply Singleton pattern, Replace reflection with Type Factory + sync.Pool for optimization, Optimize file release process
Build / build (push) Successful in 8m47s
2025-10-19 13:20:56 +07:00
Kain344 0a44f56c2f Re-optima apk
Build / build (push) Successful in 6m3s
2025-10-18 09:13:43 +07:00
Kain344 527c8176e4 FIX: Update new resource
Build / build (push) Successful in 7m18s
2025-10-17 12:31:30 +07:00
Kain344 a54219b781 FIX: Update new resource
Build / build (push) Failing after 3m37s
2025-10-17 12:24:53 +07:00
22 changed files with 12428 additions and 4887 deletions
+6 -2
View File
@@ -1,7 +1,11 @@
name: Build name: Build
run-name: ${{ gitea.actor }} build 🚀 run-name: ${{ gitea.actor }} build 🚀
on: [push] on:
push:
branches:
- master
jobs: jobs:
build: build:
@@ -13,7 +17,7 @@ jobs:
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: '21.0.7' java-version: '17'
- name: Setup Android SDK - name: Setup Android SDK
uses: amyu/setup-android@v5 uses: amyu/setup-android@v5
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" /> <bytecodeTargetLevel target="17" />
</component> </component>
</project> </project>
+1 -1
View File
@@ -6,7 +6,6 @@
<GradleProjectSettings> <GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" /> <option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
@@ -15,5 +14,6 @@
</option> </option>
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
<option name="parallelModelFetch" value="true" />
</component> </component>
</project> </project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownSettings">
<option name="previewPanelProviderInfo">
<ProviderInfo name="Compose (experimental)" className="com.intellij.markdown.compose.preview.ComposePanelProvider" />
</option>
</component>
</project>
+1 -2
View File
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">
+18 -21
View File
@@ -1,14 +1,19 @@
@file:Suppress("UnstableApiUsage") @file:Suppress("UnstableApiUsage")
import com.android.build.api.dsl.Packaging
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose) alias(libs.plugins.kotlin.compose)
} }
kotlin {
jvmToolchain(17)
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
android { android {
namespace = "com.example.firefly_go_android" namespace = "com.example.firefly_go_android"
compileSdk = 36 compileSdk = 36
@@ -16,36 +21,27 @@ android {
defaultConfig { defaultConfig {
applicationId = "com.kain344.firefly_go_android" applicationId = "com.kain344.firefly_go_android"
minSdk = 24 minSdk = 24
//noinspection OldTargetApi
targetSdk = 35 targetSdk = 35
versionCode = 1 versionCode = 2
versionName = "1.0" versionName = "1.0.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
fun Packaging.() {
jniLibs {
useLegacyPackaging = true
}
}
buildTypes { buildTypes {
release { release {
isMinifyEnabled = false isMinifyEnabled = true
isShrinkResources = true
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"
) )
ndk {
abiFilters.addAll(listOf("arm64-v8a"))
} }
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
} }
buildFeatures { buildFeatures {
@@ -101,5 +97,6 @@ dependencies {
// Local AAR library // Local AAR library
implementation(files("libs/firefly-go.aar")) implementation(files("libs/firefly-go.aar"))
}
implementation(libs.slf4j.android)
}
BIN
View File
Binary file not shown.
+20 -6
View File
@@ -2,12 +2,22 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /> tools:ignore="ForegroundServicesPolicy" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
tools:ignore="RequestInstallPackagesPolicy" />
<uses-permission android:name="android.permission.READ_LOGS"/> <uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -20,6 +30,7 @@
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:theme="@style/Theme.FireflyGoAndroid" android:theme="@style/Theme.FireflyGoAndroid"
tools:targetApi="31"> tools:targetApi="31">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@@ -32,9 +43,12 @@
<service <service
android:name=".GolangServerService" android:name=".GolangServerService"
android:foregroundServiceType="dataSync" android:foregroundServiceType="specialUse"
android:exported="false" /> android:exported="false">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Running local Golang TCP/UDP Server" />
</service>
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
+588
View File
@@ -0,0 +1,588 @@
{
"leader": 2,
"lineups": {
"0": 1409,
"1": 1407,
"2": 1406,
"3": 1403
},
"position": {
"x": -4030,
"z": -13006,
"y": 0,
"rot_y": 270000
},
"scene": {
"plane_id": 10000,
"floor_id": 10000000,
"entry_id": 100000104
},
"player_outfit": [
1003
],
"char_path": {
"main": 8008,
"march_7": 1224
},
"char_enhanced": {
"1004": 1,
"1005": 0,
"1006": 1,
"1102": 1,
"1205": 1,
"1212": 1,
"1217": 1,
"1306": 1,
"1307": 1,
"1310": 1
},
"challenge": {
"challenge_id": 0,
"skip_half": 0,
"random_seed": 0,
"blessings": [],
"is_in_challenge": false,
"current_stage_id": 0,
"path_resonance_id": 0,
"maze_buff": 0,
"first_lineup": [],
"second_lineup": []
},
"challenge_tierce": {
"challenge_id": 0,
"current_stage_id": 0,
"maze_buff": 0,
"path_resonance_id": 0,
"is_in_challenge": false,
"is_single_stage": false,
"challenge_tierce_data": {
"20245": {
"stage_1": {
"blessing": 3031361,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 40000,
"lineup": [
1407,
1413,
1415,
1409
]
},
"stage_2": {
"blessing": 3031361,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 40000,
"lineup": [
1310,
1225,
1321,
1222
]
},
"stage_3": {
"blessing": 3031362,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 40000,
"lineup": [
1506,
1502,
1501,
1217
]
}
},
"30185": {
"stage_1": {
"blessing": 3111090,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 3932,
"lineup": [
1501,
1502,
1414,
1506
]
},
"stage_2": {
"blessing": 3111085,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 3913,
"lineup": [
1310,
1225,
1303,
1321
]
},
"stage_3": {
"blessing": 3111071,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 4000,
"lineup": [
1415,
1413,
1407,
1409
]
}
},
"5213": {
"stage_1": {
"blessing": 0,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 0,
"lineup": [
1407,
1413,
1415,
1409
]
},
"stage_2": {
"blessing": 0,
"cycle_count": 1,
"battle_status": 1,
"DeadCount": 0,
"score": 0,
"lineup": [
1310,
1321,
1225,
1222
]
},
"stage_3": {
"blessing": 0,
"cycle_count": 0,
"battle_status": 1,
"DeadCount": 0,
"score": 0,
"lineup": [
1506,
1502,
1501,
1414
]
}
},
"5313": {
"stage_1": {
"blessing": 0,
"cycle_count": 0,
"battle_status": 3,
"DeadCount": 0,
"score": 0,
"lineup": [
1510,
8001,
1004,
1414
]
},
"stage_2": {
"blessing": 0,
"cycle_count": 0,
"battle_status": 0,
"DeadCount": 0,
"score": 0,
"lineup": [
1302
]
},
"stage_3": {
"blessing": 0,
"cycle_count": 0,
"battle_status": 0,
"DeadCount": 0,
"score": 0,
"lineup": [
1321
]
}
}
}
},
"challenge_peak": {
"current_mode": "Knight",
"group_id": 8,
"is_in_challenge_peak": false,
"challenge_peak_data": {
"1": {
"checkmate_data": {
"challenge_id": 104,
"blessing": 3033006,
"lineup": [
1413,
1409,
1407,
1403
],
"stage_id": 30501022,
"is_hard_mode": true
},
"knight_data": {
"current_challenge_id": 103,
"details_data": [
{
"lineup": [
1222,
1225,
1310,
1303
],
"stage_id": 30501011,
"challenge_id": 101
},
{
"lineup": [
1412,
1414,
1408,
1313
],
"stage_id": 30501012,
"challenge_id": 102
},
{
"lineup": [
1407,
1403,
1409,
1413
],
"stage_id": 30501013,
"challenge_id": 103
}
]
}
},
"2": {
"checkmate_data": {
"challenge_id": 204,
"blessing": 3033021,
"lineup": [
1415,
1413,
1409,
1407
],
"stage_id": 30502022,
"is_hard_mode": true
},
"knight_data": {
"current_challenge_id": 203,
"details_data": [
{
"lineup": [
1302,
1309,
1410
],
"stage_id": 30502011,
"challenge_id": 201
},
{
"lineup": [
1221,
1222
],
"stage_id": 30502012,
"challenge_id": 202
},
{
"lineup": [
1415,
8001,
1414,
1313
],
"stage_id": 30502013,
"challenge_id": 203
}
]
}
},
"3": {
"checkmate_data": {
"challenge_id": 304,
"blessing": 3033032,
"lineup": [
1222,
1225,
1310,
1321
],
"stage_id": 30503021,
"is_hard_mode": false
},
"knight_data": {
"current_challenge_id": 302,
"details_data": [
{
"lineup": [
1003
],
"stage_id": 30503011,
"challenge_id": 301
},
{
"lineup": [
1315
],
"stage_id": 30503012,
"challenge_id": 302
},
{
"lineup": [
8001
],
"stage_id": 30503013,
"challenge_id": 303
}
]
}
},
"4": {
"checkmate_data": {
"challenge_id": 404,
"blessing": 3033045,
"lineup": [
1310
],
"stage_id": 30504021,
"is_hard_mode": false
},
"knight_data": {
"current_challenge_id": 401,
"details_data": [
{
"lineup": [
1302
],
"stage_id": 30504011,
"challenge_id": 401
},
{
"lineup": [
1321
],
"stage_id": 30504012,
"challenge_id": 402
},
{
"lineup": [
1218
],
"stage_id": 30504013,
"challenge_id": 403
}
]
}
},
"5": {
"checkmate_data": {
"challenge_id": 504,
"blessing": 3033050,
"lineup": [
1415,
1413,
1407,
1409
],
"stage_id": 30505021,
"is_hard_mode": false
},
"knight_data": {
"current_challenge_id": 501,
"details_data": [
{
"lineup": [
1310
],
"stage_id": 30505011,
"challenge_id": 501
},
{
"lineup": [
1407
],
"stage_id": 30505012,
"challenge_id": 502
},
{
"lineup": [
1502
],
"stage_id": 30505013,
"challenge_id": 503
}
]
}
},
"6": {
"checkmate_data": {
"challenge_id": 604,
"blessing": 3033053,
"lineup": [
1505,
1217,
1502,
8001
],
"stage_id": 30506021,
"is_hard_mode": false
},
"knight_data": {
"current_challenge_id": 602,
"details_data": [
{
"lineup": [
1309
],
"stage_id": 30506011,
"challenge_id": 601
},
{
"lineup": [
1321,
1310,
1225,
1303
],
"stage_id": 30506012,
"challenge_id": 602
},
{
"lineup": [
1415,
1413,
1409,
1407
],
"stage_id": 30506013,
"challenge_id": 603
}
]
}
},
"7": {
"checkmate_data": {
"challenge_id": 704,
"blessing": 3033061,
"lineup": [
1505,
1502,
1414,
1410
],
"stage_id": 30507021,
"is_hard_mode": false
},
"knight_data": {
"current_challenge_id": 703,
"details_data": [
{
"lineup": [
1414
],
"stage_id": 30507011,
"challenge_id": 701
},
{
"lineup": [
1501
],
"stage_id": 30507012,
"challenge_id": 702
},
{
"lineup": [
1507,
1222
],
"stage_id": 30507013,
"challenge_id": 703
}
]
}
},
"8": {
"checkmate_data": {
"challenge_id": 0,
"blessing": 0,
"lineup": null,
"stage_id": 0,
"is_hard_mode": false
},
"knight_data": {
"current_challenge_id": 0,
"details_data": null
}
}
}
},
"theory_craft": {
"hp": {
"1": [
200000,
1000000,
200000
],
"2": [
2000000000,
2000000000,
2000000000
],
"3": []
},
"cycle_count": 1,
"stage_id": 30118121,
"mode": false,
"custom_lineup": []
},
"profile_data": {
"cur_chat_bubble_id": 220009,
"cur_phone_theme_id": 221012,
"cur_phone_case_id": 254001,
"cur_pam_skin_id": 252000,
"cur_pet_id": 0,
"cur_avatar_player_icon": 202034,
"cur_player_personal_card": 253001,
"cur_signature": "Firefly GO By Kain",
"cur_nickname": "Firefly GO",
"cur_display_avatar": [
1310,
1309,
1407,
1413,
1412
],
"cur_is_display_avatar": true
},
"skin_data": {
"1001": 1100101,
"1310": 1131001,
"1407": 1140701,
"1415": 1141501
},
"extra_setting": {
"censorship": false,
"cm": false,
"first_person": false,
"hide_ui": false
}
}
File diff suppressed because it is too large Load Diff
+128
View File
@@ -0,0 +1,128 @@
{
"CNBETAAndroid4.3.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15261247_f6e6db2125cf_369da465b36faf",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15235885_6091fd15561a_83828f542dc1f3",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15265964_c2fbb1eb05fc_f2238199ee2b6e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15242148_d40f856defc0_599b68a0adf7bd",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"CNBETAAndroid4.3.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15318724_a7af31327e74_b3328eb95329b2",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15305751_09783637ccc4_d16f9c81138ab3",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"CNBETAAndroid4.3.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15385668_07011a79dadf_1111728953724e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15378559_7514340ac82f_70dad6c56b8bc7",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15384138_4e4be8cf97ac_1e3fcfa0a93bef"
},
"CNBETAWin4.3.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15261247_f6e6db2125cf_369da465b36faf",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15235885_6091fd15561a_83828f542dc1f3",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15265964_c2fbb1eb05fc_f2238199ee2b6e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15242148_d40f856defc0_599b68a0adf7bd",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"CNBETAWin4.3.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15318724_a7af31327e74_b3328eb95329b2",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15305751_09783637ccc4_d16f9c81138ab3",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"CNBETAWin4.3.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15385668_07011a79dadf_1111728953724e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15378559_7514340ac82f_70dad6c56b8bc7",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15384138_4e4be8cf97ac_1e3fcfa0a93bef"
},
"CNBETAiOS4.3.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15261247_f6e6db2125cf_369da465b36faf",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15235885_6091fd15561a_83828f542dc1f3",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15265964_c2fbb1eb05fc_f2238199ee2b6e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15242148_d40f856defc0_599b68a0adf7bd",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"CNBETAiOS4.3.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15318724_a7af31327e74_b3328eb95329b2",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15305751_09783637ccc4_d16f9c81138ab3",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"CNBETAiOS4.3.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15385668_07011a79dadf_1111728953724e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15378559_7514340ac82f_70dad6c56b8bc7",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15384138_4e4be8cf97ac_1e3fcfa0a93bef"
},
"OSBETAAndroid4.3.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15261247_f6e6db2125cf_369da465b36faf",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15235885_6091fd15561a_83828f542dc1f3",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15265964_c2fbb1eb05fc_f2238199ee2b6e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15242148_d40f856defc0_599b68a0adf7bd",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"OSBETAAndroid4.3.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15318724_a7af31327e74_b3328eb95329b2",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15305751_09783637ccc4_d16f9c81138ab3",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"OSBETAAndroid4.3.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15385668_07011a79dadf_1111728953724e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15378559_7514340ac82f_70dad6c56b8bc7",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15384138_4e4be8cf97ac_1e3fcfa0a93bef"
},
"OSBETAWin4.3.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15261247_f6e6db2125cf_369da465b36faf",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15235885_6091fd15561a_83828f542dc1f3",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15265964_c2fbb1eb05fc_f2238199ee2b6e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15242148_d40f856defc0_599b68a0adf7bd",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"OSBETAWin4.3.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15318724_a7af31327e74_b3328eb95329b2",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15305751_09783637ccc4_d16f9c81138ab3",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"OSBETAWin4.3.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15385668_07011a79dadf_1111728953724e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15378559_7514340ac82f_70dad6c56b8bc7",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15384138_4e4be8cf97ac_1e3fcfa0a93bef"
},
"OSBETAiOS4.3.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15261247_f6e6db2125cf_369da465b36faf",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15235885_6091fd15561a_83828f542dc1f3",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15265964_c2fbb1eb05fc_f2238199ee2b6e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15242148_d40f856defc0_599b68a0adf7bd",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"OSBETAiOS4.3.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15305566_fea016d35145_54bbf8ab4009f5",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15318724_a7af31327e74_b3328eb95329b2",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15305751_09783637ccc4_d16f9c81138ab3",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15265964_799df4f0ecef_5a94550ba64cff"
},
"OSBETAiOS4.3.53": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"asset_bundle_url_b": "https://autopatchos.starrails.com/asb/BetaLive/output_15378434_99bffafdeff7_5d97713dcef07f",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_15385668_07011a79dadf_1111728953724e",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_15378559_7514340ac82f_70dad6c56b8bc7",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_15384138_4e4be8cf97ac_1e3fcfa0a93bef"
}
}
@@ -1,10 +1,12 @@
package com.example.firefly_go_android package com.example.firefly_go_android
import android.annotation.SuppressLint
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.app.Service import android.app.Service
import android.content.Intent import android.content.Intent
import android.content.pm.ServiceInfo
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Build import android.os.Build
import android.os.IBinder import android.os.IBinder
@@ -16,6 +18,7 @@ import androidx.compose.runtime.setValue
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import libandroid.Libandroid import libandroid.Libandroid
import androidx.core.content.edit
class GolangServerService : Service() { class GolangServerService : Service() {
@@ -33,9 +36,10 @@ class GolangServerService : Service() {
createNotificationChannel() createNotificationChannel()
} }
@SuppressLint("WakelockTimeout")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (isRunning) { if (isRunning) {
Log.d(TAG, "Server is already running") Log.d(TAG, "Server is already running")
return START_STICKY return START_STICKY
} }
isRunning = true isRunning = true
@@ -64,42 +68,63 @@ class GolangServerService : Service() {
.setCategory(NotificationCompat.CATEGORY_SERVICE) .setCategory(NotificationCompat.CATEGORY_SERVICE)
.build() .build()
if (Build.VERSION.SDK_INT >= 34) {
startForeground(
NOTIFICATION_ID,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
)
} else if (Build.VERSION.SDK_INT >= 29) {
startForeground(
NOTIFICATION_ID,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST
)
} else {
startForeground(NOTIFICATION_ID, notification) startForeground(NOTIFICATION_ID, notification)
}
// Khởi tạo WakeLock và WifiLock
try { try {
val powerManager = getSystemService(POWER_SERVICE) as PowerManager val powerManager = getSystemService(POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "GolangServer::WakeLock") wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "GolangServer::WakeLock")
wakeLock?.acquire(10*60*1000L) wakeLock?.acquire()
Log.d(TAG, "WakeLock acquired") Log.d(TAG, "WakeLock acquired")
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "❌ WakeLock failed", e) Log.e(TAG, "Lock failed", e)
} }
Thread { Thread {
try { try {
val appDataPath = intent?.getStringExtra("appDataPath") val sharedPrefs = getSharedPreferences("AppPrefs", MODE_PRIVATE)
var appDataPath = intent?.getStringExtra("appDataPath")
if (appDataPath != null) {
sharedPrefs.edit { putString("saved_app_data_path", appDataPath) }
} else {
appDataPath = sharedPrefs.getString("saved_app_data_path", null)
}
if (appDataPath != null) { if (appDataPath != null) {
Libandroid.setPathDataLocal(appDataPath) Libandroid.setPathDataLocal(appDataPath)
Log.d(TAG, "Set path data: $appDataPath") Log.d(TAG, "Set path data: $appDataPath")
} else { } else {
isRunning = false isRunning = false
Log.e(TAG, "appDataPath not received in intent") Log.e(TAG, "appDataPath not received and not found in SharedPreferences")
stopSelf() stopSelf()
return@Thread return@Thread
} }
Libandroid.setServerRunning(true) Libandroid.setServerRunning(true)
isRunning = true isRunning = true
Log.d(TAG, "Server started") Log.d(TAG, "Server started")
} catch (e: Exception) { } catch (e: Exception) {
isRunning = false isRunning = false
Log.e(TAG, "Error starting server", e) Log.e(TAG, "Error starting server", e)
stopSelf() stopSelf()
} }
}.start() }.start()
return START_STICKY return START_STICKY
} }
@@ -107,7 +132,6 @@ class GolangServerService : Service() {
super.onDestroy() super.onDestroy()
Log.d(TAG, "onDestroy called") Log.d(TAG, "onDestroy called")
// 1. Tắt server
try { try {
val result = Libandroid.setServerRunning(false) val result = Libandroid.setServerRunning(false)
isRunning = false isRunning = false
@@ -116,15 +140,16 @@ class GolangServerService : Service() {
Log.e(TAG, "Error shutting down server", e) Log.e(TAG, "Error shutting down server", e)
} }
// Nhả các khóa tài nguyên
try { try {
wakeLock?.let { wakeLock?.let {
if (it.isHeld) { if (it.isHeld) {
it.release() it.release()
Log.d(TAG, "WakeLock released") Log.d(TAG, "WakeLock released")
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Failed to release WakeLock", e) Log.e(TAG, "Failed to release Locks", e)
} }
isRunning = false isRunning = false
} }
@@ -143,7 +168,7 @@ class GolangServerService : Service() {
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel) manager.createNotificationChannel(channel)
Log.d(TAG, "Notification channel created") Log.d(TAG, "Notification channel created")
} }
} }
} }
@@ -4,8 +4,9 @@ import AutoUpdaterManager
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
@@ -66,6 +67,12 @@ import androidx.compose.ui.window.DialogProperties
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import org.json.JSONObject import org.json.JSONObject
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import android.os.PowerManager
import android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import android.provider.Settings
data class AppVersion( data class AppVersion(
val latestVersion: String, val latestVersion: String,
@@ -76,23 +83,62 @@ data class AppVersion(
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
requestBatteryExemption(this)
requestInstallPermission(this)
requestStoragePermission(this)
val appDataPath = filesDir.absolutePath val appDataPath = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "FireflyGo").absolutePath
val dataDir = File("$appDataPath/data") val dataDir = File("$appDataPath/data")
dataDir.mkdirs() if (!dataDir.exists()) dataDir.mkdirs()
copyRawToFile(this, dataDir, "data-in-game.json", R.raw.data_in_game_json) val sharedPrefs = getSharedPreferences("AppPrefs", MODE_PRIVATE)
copyRawToFile(this, dataDir, "freesr-data.json", R.raw.freesr_data_json)
copyRawToFile(this, dataDir, "version.json", R.raw.version_json)
val jsonString = resources.openRawResource(R.raw.app_version_json).use { input -> // Lấy thông tin Package
input.bufferedReader().use { it.readText() } val packageInfo = if (Build.VERSION.SDK_INT >= 33) {
packageManager.getPackageInfo(packageName, android.content.pm.PackageManager.PackageInfoFlags.of(0))
} else {
@Suppress("DEPRECATION")
packageManager.getPackageInfo(packageName, 0)
} }
val jsonObject = JSONObject(jsonString) val currentVersionCode = if (Build.VERSION.SDK_INT >= 33) packageInfo.longVersionCode else packageInfo.versionCode.toLong()
val latestVersion = jsonObject.getString("latest_version") val currentLastUpdateTime = packageInfo.lastUpdateTime
val changelog = jsonObject.getString("changelog")
val apkUrl = jsonObject.getString("apk_url") val savedVersionCode = sharedPrefs.getLong("last_version_code", 0L)
val savedLastUpdateTime = sharedPrefs.getLong("last_update_time", 0L)
val isFolderEmpty = dataDir.listFiles()?.isEmpty() ?: true
val shouldOverride = currentVersionCode > savedVersionCode ||
currentLastUpdateTime > savedLastUpdateTime ||
isFolderEmpty
Log.i("AppUpdate", "Code: $currentVersionCode, LastUpdate: $currentLastUpdateTime")
Log.i("AppUpdate", "SavedCode: $savedVersionCode, SavedUpdate: $savedLastUpdateTime")
Log.i("AppUpdate", "Should Override: $shouldOverride")
if (copyRawToFile(this, dataDir, shouldOverride)) {
if (shouldOverride) {
sharedPrefs.edit()
.putLong("last_version_code", currentVersionCode)
.putLong("last_update_time", currentLastUpdateTime)
.apply()
Log.i("AppUpdate", "Updated SharedPreferences with new version and time")
}
}
val jsonString = try {
resources.openRawResource(R.raw.app_version_json).use { input ->
input.bufferedReader().use { it.readText() }
}
} catch (e: Exception) {
"{}"
}
val jsonObject = if (jsonString.isNotEmpty()) JSONObject(jsonString) else JSONObject()
val latestVersion = jsonObject.optString("latest_version", "1.0.0")
val changelog = jsonObject.optString("changelog", "")
val apkUrl = jsonObject.optString("apk_url", "")
val appVersion = AppVersion(latestVersion, changelog, apkUrl) val appVersion = AppVersion(latestVersion, changelog, apkUrl)
@@ -111,22 +157,82 @@ class MainActivity : ComponentActivity() {
} }
} }
@SuppressLint("BatteryLife")
fun copyRawToFile(context: Context, targetDir: File, fileName: String, resId: Int, override: Boolean = false) { fun requestBatteryExemption(context: Context) {
val outFile = File(targetDir, fileName) val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
if (!outFile.exists() || override) { if (!powerManager.isIgnoringBatteryOptimizations(context.packageName)) {
val intent = Intent().apply {
action = ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
data = "package:${context.packageName}".toUri()
}
context.startActivity(intent)
}
}
fun requestInstallPermission(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!context.packageManager.canRequestPackageInstalls()) {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
data = "package:${context.packageName}".toUri()
}
context.startActivity(intent)
Toast.makeText(context, "Please allow installing unknown apps to update", Toast.LENGTH_LONG).show()
}
}
}
fun requestStoragePermission(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (!Environment.isExternalStorageManager()) {
try { try {
context.resources.openRawResource(resId).use { input -> val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply {
data = "package:${context.packageName}".toUri()
}
context.startActivity(intent)
Toast.makeText(context, "Please allow All Files Access to load game data", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
try {
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
context.startActivity(intent)
} catch (ex: Exception) {
Log.e("StoragePermission", "Failed to open settings", ex)
}
}
}
}
}
fun copyRawToFile(context: Context, targetDir: File, override: Boolean = false): Boolean {
val files = listOf(
"data-in-game.json" to "data-in-game.json",
"freesr-data.json" to "freesr-data.json",
"version.json" to "version.json"
)
return try {
if (!targetDir.exists()) targetDir.mkdirs()
for ((assetFile, outName) in files) {
val outFile = File(targetDir, outName)
if (outFile.exists() && !override) {
Log.i("CopyRaw", "Skipping $outName (already exists and no override)")
continue
}
Log.i("CopyRaw", "Copying $assetFile to ${outFile.absolutePath} (Override: $override)")
context.assets.open(assetFile).use { input ->
FileOutputStream(outFile).use { output -> FileOutputStream(outFile).use { output ->
input.copyTo(output) input.copyTo(output)
output.fd.sync()
} }
} }
Log.i("FileCopy", "${if (override) "✅ Overridden" else "✅ Copied"} $fileName to ${outFile.absolutePath}") }
true
} catch (e: Exception) { } catch (e: Exception) {
Log.e("FileCopy", "❌ Failed to copy $fileName: ${e.message}") Log.e("CopyRaw", "Error copying asset file: ${e.message}", e)
} false
} else {
Log.i("FileCopy", "$fileName already exists at ${outFile.absolutePath}")
} }
} }
@@ -135,18 +241,18 @@ fun removeFile(targetDir: File, fileName: String): Boolean {
return if (file.exists()) { return if (file.exists()) {
try { try {
if (file.delete()) { if (file.delete()) {
Log.i("FileRemove", "🗑️ Removed $fileName from ${file.absolutePath}") Log.i("FileRemove", "Removed $fileName from ${file.absolutePath}")
true true
} else { } else {
Log.e("FileRemove", "Failed to remove $fileName from ${file.absolutePath}") Log.e("FileRemove", "Failed to remove $fileName from ${file.absolutePath}")
false false
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e("FileRemove", "Error removing $fileName: ${e.message}") Log.e("FileRemove", "Error removing $fileName: ${e.message}")
false false
} }
} else { } else {
Log.i("FileRemove", "$fileName does not exist in ${targetDir.absolutePath}") Log.i("FileRemove", "$fileName does not exist in ${targetDir.absolutePath}")
false false
} }
} }
@@ -238,7 +344,7 @@ fun ServerControlScreen(appDataPath: String, dataDir: File, appVersion: AppVersi
if (!isRunning) { if (!isRunning) {
val intent = Intent(context, GolangServerService::class.java) val intent = Intent(context, GolangServerService::class.java)
intent.putExtra("appDataPath", appDataPath) intent.putExtra("appDataPath", appDataPath)
context.startService(intent) ContextCompat.startForegroundService(context, intent)
} else { } else {
context.stopService(Intent(context, GolangServerService::class.java)) context.stopService(Intent(context, GolangServerService::class.java))
} }
@@ -271,7 +377,8 @@ fun ServerControlScreen(appDataPath: String, dataDir: File, appVersion: AppVersi
// Widget icons row // Widget icons row
Row( Row(
horizontalArrangement = Arrangement.spacedBy(32.dp), modifier = Modifier.fillMaxWidth(0.85f),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
@@ -279,6 +386,7 @@ fun ServerControlScreen(appDataPath: String, dataDir: File, appVersion: AppVersi
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.width(80.dp)
.clickable { showUpdateDialog = true } .clickable { showUpdateDialog = true }
.background( .background(
Color.White.copy(alpha = 0.8f), Color.White.copy(alpha = 0.8f),
@@ -306,6 +414,7 @@ fun ServerControlScreen(appDataPath: String, dataDir: File, appVersion: AppVersi
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.width(80.dp)
.clickable { showResetDialog = true } .clickable { showResetDialog = true }
.background( .background(
Color.White.copy(alpha = 0.8f), Color.White.copy(alpha = 0.8f),
@@ -333,6 +442,7 @@ fun ServerControlScreen(appDataPath: String, dataDir: File, appVersion: AppVersi
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier modifier = Modifier
.width(80.dp)
.clickable { .clickable {
showLogs = true // mở popup log showLogs = true // mở popup log
} }
@@ -381,9 +491,7 @@ fun ServerControlScreen(appDataPath: String, dataDir: File, appVersion: AppVersi
onClick = { onClick = {
showResetDialog = false showResetDialog = false
try { try {
copyRawToFile(context, dataDir, "data-in-game.json", R.raw.data_in_game_json, true) copyRawToFile(context, dataDir, true)
copyRawToFile(context, dataDir, "freesr-data.json", R.raw.freesr_data_json, true)
copyRawToFile(context, dataDir, "version.json", R.raw.version_json, true)
Toast.makeText(context, "Data has been reset successfully", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Data has been reset successfully", Toast.LENGTH_SHORT).show()
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText(context, "Reset failed: ${e.message}", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Reset failed: ${e.message}", Toast.LENGTH_SHORT).show()
@@ -421,64 +529,60 @@ fun parseGoLogLine(line: String): String? {
return if (content.isNullOrBlank()) null else content return if (content.isNullOrBlank()) null else content
} }
fun parseAnsi(text: String): AnnotatedString {
fun parseAnsi(text: String, defaultColor: Color): AnnotatedString {
val regex = Regex("\u001B\\[(\\d+)(;\\d+)*m") val regex = Regex("\u001B\\[(\\d+)(;\\d+)*m")
val builder = buildAnnotatedString { val builder = buildAnnotatedString {
var lastIndex = 0 var lastIndex = 0
var currentColor = Color.Black var currentColor = defaultColor
for (match in regex.findAll(text)) { for (match in regex.findAll(text)) {
val start = match.range.first val start = match.range.first
// 1. Thêm phần text TRƯỚC mã ANSI với màu HIỆN TẠI
val before = text.substring(lastIndex, start) val before = text.substring(lastIndex, start)
if (before.isNotEmpty()) {
withStyle(SpanStyle(color = currentColor)) { withStyle(SpanStyle(color = currentColor)) {
append(before) append(before)
} }
}
// 2. Lấy mã code (ví dụ 31, 36, hoặc 0)
val code = try {
match.groupValues[1].toInt()
} catch (e: NumberFormatException) {
0
}
val code = match.groupValues[1].toInt()
currentColor = when (code) { currentColor = when (code) {
30 -> { 0 -> defaultColor
Color.Black 30 -> Color.Black
} 31 -> Color.Red
31 -> { 32 -> Color(0xFF00C853) // Green
Color.Red 33 -> Color(0xFFFFD600) // Yellow
} 34 -> Color(0xFF2962FF) // Blue
32 -> { 35 -> Color(0xFFD500F9) // Magenta
Color(0xFF00C853) 36 -> Color(0xFF00B8D4) // Cyan
} 37 -> Color.White
33 -> { else -> currentColor
Color(0xFFFFD600)
}
34 -> {
Color(0xFF2962FF)
}
35 -> {
Color(0xFFD500F9)
}
36 -> {
Color(0xFF00B8D4)
}
37 -> {
Color.White
}
else -> {
Color.Black
}
} }
lastIndex = match.range.last + 1 lastIndex = match.range.last + 1
} }
if (lastIndex < text.length) {
val remain = text.substring(lastIndex) val remain = text.substring(lastIndex)
if (remain.isNotEmpty()) {
withStyle(SpanStyle(color = currentColor)) { withStyle(SpanStyle(color = currentColor)) {
append(remain) append(remain)
} }
} }
}
}
return builder return builder
} }
@Composable @Composable
fun LogPopup( fun LogPopup(
onDismiss: () -> Unit onDismiss: () -> Unit
@@ -512,6 +616,8 @@ fun LogPopup(
} }
} }
val defaultTextColor = LocalContentColor.current
Dialog(onDismissRequest = { onDismiss() }) { Dialog(onDismissRequest = { onDismiss() }) {
Surface( Surface(
shape = RoundedCornerShape(12.dp), shape = RoundedCornerShape(12.dp),
@@ -531,8 +637,15 @@ fun LogPopup(
LazyColumn(state = listState, modifier = Modifier.weight(1f)) { LazyColumn(state = listState, modifier = Modifier.weight(1f)) {
items(logs.size) { index -> items(logs.size) { index ->
Text( Text(
text = parseAnsi(logs[index]), text = parseAnsi(logs[index], defaultTextColor),
fontSize = 12.sp, fontSize = 12.sp,
// 2. DÙNG FONT MONOSPACE
fontFamily = FontFamily.Monospace,
// 3. (Tuỳ chọn) Giảm chiều cao dòng để logo liền mạch
lineHeight = 14.sp,
modifier = Modifier.padding(vertical = 2.dp) modifier = Modifier.padding(vertical = 2.dp)
) )
} }
@@ -562,7 +675,7 @@ fun AutoUpdateDialog(
val context = LocalContext.current val context = LocalContext.current
val autoUpdaterManager = AutoUpdaterManager(context) val autoUpdaterManager = AutoUpdaterManager(context)
var update by remember { mutableStateOf<UpdateFeatures?>(null) } var update by remember { mutableStateOf<UpdateFeatures?>(null) }
var progress by remember { mutableIntStateOf(0) } var progress by remember { mutableStateOf(0) }
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
var isDownloading by remember { mutableStateOf(false) } var isDownloading by remember { mutableStateOf(false) }
var downloadComplete by remember { mutableStateOf(false) } var downloadComplete by remember { mutableStateOf(false) }
@@ -604,11 +717,6 @@ fun AutoUpdateDialog(
LaunchedEffect(progress) { LaunchedEffect(progress) {
if (progress >= 100 && isDownloading) { if (progress >= 100 && isDownloading) {
downloadComplete = true downloadComplete = true
removeFile(dataDir, "data-in-game.json" )
removeFile(dataDir, "freesr-data.json")
removeFile(dataDir, "version.json")
delay(500)
} }
} }
+3 -3
View File
@@ -1,5 +1,5 @@
{ {
"latest_version": "3.6.4-01", "latest_version": "4.3.3-01",
"changelog": "UPDATE: Update to 3.6.54", "changelog": "UPDATE: 4.3.5X",
"apk_url": "https://git.kain.io.vn/Firefly-Shelter/FireflyGo_Android/releases/download/3.6.4-01/firefly_go_android.apk" "apk_url": "https://git.kain.io.vn/Firefly-Shelter/FireflyGo_Android/releases/download/4.3.3-01/firefly_go_android.apk"
} }
-184
View File
@@ -1,184 +0,0 @@
{
"leader": 0,
"lineups": {
"0": 1413,
"1": 1415,
"2": 1409,
"3": 1407
},
"position": {
"x": 218004,
"z": 259263,
"y": 53915,
"rot_y": 79863
},
"scene": {
"plane_id": 20423,
"floor_id": 20423001,
"entry_id": 2042301
},
"player_outfit": [
1001
],
"char_path": {
"main": 8008,
"march_7": 1224
},
"char_enhanced": {
"1005": 1,
"1006": 1,
"1205": 1,
"1212": 1
},
"challenge": {
"challenge_id": 0,
"skip_half": 0,
"blessings": [],
"is_in_challenge": false,
"current_stage_id": 30118121,
"path_resonance_id": 0,
"maze_buff": 0,
"first_lineup": [],
"second_lineup": []
},
"challenge_peak": {
"current_mode": "Knight",
"group_id": 2,
"is_in_challenge_peak": false,
"challenge_peak_data": {
"1": {
"checkmate_data": {
"challenge_id": 104,
"blessing": 3033006,
"lineup": [
1413,
1409,
1407,
1403
],
"stage_id": 30501022,
"is_hard_mode": true
},
"knight_data": {
"current_challenge_id": 103,
"details_data": [
{
"lineup": [
1222,
1225,
1310,
1303
],
"stage_id": 30501011,
"challenge_id": 101
},
{
"lineup": [
1412,
1414,
1408,
1313
],
"stage_id": 30501012,
"challenge_id": 102
},
{
"lineup": [
1407,
1403,
1409,
1413
],
"stage_id": 30501013,
"challenge_id": 103
}
]
}
},
"2": {
"checkmate_data": {
"challenge_id": 204,
"blessing": 3033021,
"lineup": [
1415,
1413,
1409,
1407
],
"stage_id": 30502022,
"is_hard_mode": true
},
"knight_data": {
"current_challenge_id": 203,
"details_data": [
{
"lineup": [
1302,
1309,
1410
],
"stage_id": 30502011,
"challenge_id": 201
},
{
"lineup": [
1221,
1222
],
"stage_id": 30502012,
"challenge_id": 202
},
{
"lineup": [
1415,
8001,
1414,
1313
],
"stage_id": 30502013,
"challenge_id": 203
}
]
}
}
}
},
"theory_craft": {
"hp": {
"1": [
200000,
1000000,
200000
],
"2": [
500000,
10000000,
500000
]
},
"cycle_count": 1,
"mode": true
},
"profile_data": {
"cur_chat_bubble_id": 220008,
"cur_phone_theme_id": 221012,
"cur_phone_case_id": 254001,
"cur_pam_skin_id": 252000,
"cur_pet_id": 1003,
"cur_avatar_player_icon": 202034,
"cur_player_personal_card": 253001,
"cur_signature": "Firefly GO By Kain",
"cur_display_avatar": [
1310,
1309,
1407,
1413,
1412
],
"cur_is_display_avatar": true
},
"skin_data": {
"1001": 1100101,
"1310": 1131001
}
}
-44
View File
@@ -1,44 +0,0 @@
{
"CNBETAAndroid3.6.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12066992_f083970b907e_999074cab6dce6",
"asset_bundle_url_b": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12056690_16bfd67c199f_f3c0367d7b051e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_12114942_e99cbde25134_e63a6b835f17f9",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_12103115_ee78155e9867_3626f0948d93e2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_12118783_55113408814f_c874267d04c04a"
},
"CNBETAWin3.6.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12066992_f083970b907e_999074cab6dce6",
"asset_bundle_url_b": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12056690_16bfd67c199f_f3c0367d7b051e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_12114942_e99cbde25134_e63a6b835f17f9",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_12103115_ee78155e9867_3626f0948d93e2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_12118783_55113408814f_c874267d04c04a"
},
"CNBETAiOS3.6.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12066992_f083970b907e_999074cab6dce6",
"asset_bundle_url_b": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12056690_16bfd67c199f_f3c0367d7b051e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_12114942_e99cbde25134_e63a6b835f17f9",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_12103115_ee78155e9867_3626f0948d93e2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_12118783_55113408814f_c874267d04c04a"
},
"OSBETAAndroid3.6.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12066992_f083970b907e_999074cab6dce6",
"asset_bundle_url_b": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12056690_16bfd67c199f_f3c0367d7b051e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_12114942_e99cbde25134_e63a6b835f17f9",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_12103115_ee78155e9867_3626f0948d93e2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_12118783_55113408814f_c874267d04c04a"
},
"OSBETAWin3.6.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12066992_f083970b907e_999074cab6dce6",
"asset_bundle_url_b": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12056690_16bfd67c199f_f3c0367d7b051e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_12114942_e99cbde25134_e63a6b835f17f9",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_12103115_ee78155e9867_3626f0948d93e2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_12118783_55113408814f_c874267d04c04a"
},
"OSBETAiOS3.6.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12066992_f083970b907e_999074cab6dce6",
"asset_bundle_url_b": "https://autopatchcn.bhsr.com/asb/BetaLive/output_12056690_16bfd67c199f_f3c0367d7b051e",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_12114942_e99cbde25134_e63a6b835f17f9",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_12103115_ee78155e9867_3626f0948d93e2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_12118783_55113408814f_c874267d04c04a"
}
}
+2
View File
@@ -23,3 +23,5 @@ kotlin.code.style=official
# thereby reducing the size of the R class for that library # thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true android.nonTransitiveRClass=true
#org.gradle.configuration-cache=false #org.gradle.configuration-cache=false
android.r8.optimizedResourceShrinking=true
org.gradle.java.installations.auto-download=true
+13
View File
@@ -0,0 +1,13 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/398ffe3949748bfb1d5636f023d228fd/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/398ffe3949748bfb1d5636f023d228fd/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e99bae143b75f9a10ead10248f02055e/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/658299a896470fbb3103ba3a430ee227/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/536afcd1dff540251f85e5d2c80458cf/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/398ffe3949748bfb1d5636f023d228fd/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/248ffb1098f61659502d0c09aa348294/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/932015f6361ccaead0c6d9b8717ed96e/redirect
toolchainVendor=JETBRAINS
toolchainVersion=21
+11 -9
View File
@@ -2,23 +2,24 @@
activityComposeVersion = "1.11.0" activityComposeVersion = "1.11.0"
agp = "8.13.0" agp = "8.13.0"
androidxJunit = "1.3.0" androidxJunit = "1.3.0"
animationCore = "1.9.2" animationCore = "1.9.3"
autoupdater = "1.0.1" autoupdater = "1.0.1"
espressoCoreVersion = "3.7.0" espressoCoreVersion = "3.7.0"
foundation = "1.9.2" foundation = "1.9.3"
kotlin = "2.2.20" kotlin = "2.2.20"
coreKtx = "1.17.0" coreKtx = "1.17.0"
junit = "4.13.2" junit = "4.13.2"
lifecycleRuntimeKtxVersion = "2.9.4" lifecycleRuntimeKtxVersion = "2.9.4"
material = "1.9.2" material = "1.9.3"
material3WindowSizeClass = "1.4.0" material3WindowSizeClass = "1.4.0"
materialIconsExtended = "1.7.8" materialIconsExtended = "1.7.8"
ui = "1.9.2" slf4jAndroidVersion = "1.7.36"
uiGraphics = "1.9.2" ui = "1.9.3"
uiTestJunit4 = "1.9.2" uiGraphics = "1.9.3"
uiTestManifest = "1.9.2" uiTestJunit4 = "1.9.3"
uiTooling = "1.9.2" uiTestManifest = "1.9.3"
uiToolingPreview = "1.9.2" uiTooling = "1.9.3"
uiToolingPreview = "1.9.3"
[libraries] [libraries]
androidx-activity-compose-v1101 = { module = "androidx.activity:activity-compose", version.ref = "activityComposeVersion" } androidx-activity-compose-v1101 = { module = "androidx.activity:activity-compose", version.ref = "activityComposeVersion" }
@@ -35,6 +36,7 @@ androidx-material3-window-size-class1 = { module = "androidx.compose.material3:m
autoupdater = { module = "com.github.CSAbhiOnline:AutoUpdater", version.ref = "autoupdater" } autoupdater = { module = "com.github.CSAbhiOnline:AutoUpdater", version.ref = "autoupdater" }
junit = { group = "junit", name = "junit", version.ref = "junit" } junit = { group = "junit", name = "junit", version.ref = "junit" }
material3 = { module = "androidx.compose.material3:material3", version.ref = "material3WindowSizeClass" } material3 = { module = "androidx.compose.material3:material3", version.ref = "material3WindowSizeClass" }
slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4jAndroidVersion" }
ui = { module = "androidx.compose.ui:ui", version.ref = "ui" } ui = { module = "androidx.compose.ui:ui", version.ref = "ui" }
ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "uiGraphics" } ui-graphics = { module = "androidx.compose.ui:ui-graphics", version.ref = "uiGraphics" }
ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "uiTestJunit4" } ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "uiTestJunit4" }
+2 -1
View File
@@ -1,2 +1,3 @@
# Changelog # Changelog
## - UPDATE: Update to 3.6.54
## - UPDATE: Support 4.3.5X
+2 -3
View File
@@ -1,5 +1,4 @@
{ {
"tag": "3.6.4-01", "tag": "4.3.3-01",
"title": "PreBuild Version 3.6.54 - 01" "title": "PreBuild Version 4.3.53 - 01"
} }
+3
View File
@@ -15,6 +15,9 @@ pluginManagement {
} }
} }
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.10.0"
}
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {