v0.8.0: added an update notification service
This commit is contained in:
parent
2e533b74db
commit
2138ad24ec
|
@ -28,6 +28,7 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
|
@ -35,7 +36,6 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PushbackInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
@ -45,6 +45,8 @@ import java.util.zip.GZIPOutputStream;
|
|||
public class Bundle {
|
||||
|
||||
private static final String CLASS_NAME = "__className";
|
||||
|
||||
public static final String DEFAULT_KEY = "key";
|
||||
|
||||
private static HashMap<String,String> aliases = new HashMap<>();
|
||||
|
||||
|
@ -223,6 +225,25 @@ public class Bundle {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Bundle[] getBundleArray(){
|
||||
return getBundleArray( DEFAULT_KEY );
|
||||
}
|
||||
|
||||
public Bundle[] getBundleArray( String key ){
|
||||
try {
|
||||
JSONArray array = data.getJSONArray( key );
|
||||
int length = array.length();
|
||||
Bundle[] result = new Bundle[length];
|
||||
for (int i=0; i < length; i++) {
|
||||
result[i] = new Bundle( array.getJSONObject( i ) );
|
||||
}
|
||||
return result;
|
||||
} catch (JSONException e) {
|
||||
Game.reportException(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Bundlable> getCollection( String key ) {
|
||||
|
||||
|
@ -410,22 +431,32 @@ public class Bundle {
|
|||
public static Bundle read( InputStream stream ) throws IOException {
|
||||
|
||||
try {
|
||||
BufferedReader reader;
|
||||
if (!stream.markSupported()){
|
||||
stream = new BufferedInputStream( stream, 2 );
|
||||
}
|
||||
|
||||
//determines if we're reading a regular, or compressed file
|
||||
PushbackInputStream pb = new PushbackInputStream( stream, 2 );
|
||||
stream.mark( 2 );
|
||||
byte[] header = new byte[2];
|
||||
pb.unread(header, 0, pb.read(header));
|
||||
stream.read( header );
|
||||
stream.reset();
|
||||
|
||||
//GZIP header is 0x1f8b
|
||||
if( header[ 0 ] == (byte) 0x1f && header[ 1 ] == (byte) 0x8b )
|
||||
reader = new BufferedReader( new InputStreamReader( new GZIPInputStream( pb, GZIP_BUFFER ) ) );
|
||||
else
|
||||
reader = new BufferedReader( new InputStreamReader( pb ) );
|
||||
if( header[ 0 ] == (byte) 0x1f && header[ 1 ] == (byte) 0x8b ) {
|
||||
stream = new GZIPInputStream( stream, GZIP_BUFFER );
|
||||
}
|
||||
|
||||
JSONObject json = (JSONObject)new JSONTokener( reader.readLine() ).nextValue();
|
||||
//cannot just tokenize the stream directly as that constructor doesn't exist on Android
|
||||
BufferedReader reader = new BufferedReader( new InputStreamReader( stream ));
|
||||
Object json = new JSONTokener( reader.readLine() ).nextValue();
|
||||
reader.close();
|
||||
|
||||
return new Bundle( json );
|
||||
//if the data is an array, put it in a fresh object with the default key
|
||||
if (json instanceof JSONArray){
|
||||
json = new JSONObject().put( DEFAULT_KEY, json );
|
||||
}
|
||||
|
||||
return new Bundle( (JSONObject) json );
|
||||
} catch (Exception e) {
|
||||
Game.reportException(e);
|
||||
throw new IOException();
|
||||
|
|
|
@ -28,6 +28,8 @@ public abstract class PlatformSupport {
|
|||
public abstract void updateDisplaySize();
|
||||
|
||||
public abstract void updateSystemUI();
|
||||
|
||||
public abstract boolean connectedToUnmeteredNetwork();
|
||||
|
||||
//FIXME this is currently used because no platform-agnostic text input has been implemented.
|
||||
//should look into doing that using either plain openGL or Libgdx's libraries
|
||||
|
|
|
@ -25,6 +25,9 @@ android {
|
|||
debug {
|
||||
applicationIdSuffix ".indev"
|
||||
versionNameSuffix '-INDEV'
|
||||
dependencies {
|
||||
debugImplementation project(':services:updates:debugUpdates')
|
||||
}
|
||||
}
|
||||
release {
|
||||
|
||||
|
@ -35,6 +38,10 @@ android {
|
|||
shrinkResources true
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
|
||||
dependencies {
|
||||
releaseImplementation project(':services:updates:githubUpdates')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
<uses-feature android:glEsVersion="0x00020000"/>
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<!-- Note that the game doesn't truly support small screen resolutions,
|
||||
it instead forces downscaling to work on these displays.-->
|
||||
|
|
|
@ -32,6 +32,8 @@ import com.badlogic.gdx.backends.android.AndroidApplication;
|
|||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.UpdateImpl;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.FileUtils;
|
||||
|
||||
|
@ -58,9 +60,13 @@ public class AndroidGame extends AndroidApplication {
|
|||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Game.versionCode = 0;
|
||||
}
|
||||
|
||||
if (UpdateImpl.supportsUpdates()){
|
||||
Updates.service = UpdateImpl.getUpdateService();
|
||||
}
|
||||
|
||||
FileUtils.setDefaultFileProperties( Files.FileType.Local, "" );
|
||||
|
||||
|
||||
// grab preferences directly using our instance first
|
||||
// so that we don't need to rely on Gdx.app, which isn't initialized yet.
|
||||
SPDSettings.set(instance.getPreferences("ShatteredPixelDungeon"));
|
||||
|
@ -91,7 +97,7 @@ public class AndroidGame extends AndroidApplication {
|
|||
initialize(new ShatteredPixelDungeon(support), config);
|
||||
|
||||
view = (GLSurfaceView)graphics.getView();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.android;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
@ -140,6 +143,23 @@ public class AndroidPlatformSupport extends PlatformSupport {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean connectedToUnmeteredNetwork() {
|
||||
//Returns true if using unmetered connection, use shortcut method if available
|
||||
ConnectivityManager cm = (ConnectivityManager) AndroidGame.instance.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
|
||||
return !cm.isActiveNetworkMetered();
|
||||
} else {
|
||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||
return activeNetwork != null && activeNetwork.isConnectedOrConnecting() &&
|
||||
(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_WIMAX
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_BLUETOOTH
|
||||
|| activeNetwork.getType() == ConnectivityManager.TYPE_ETHERNET);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void promptTextInput(final String title, final String hintText, final int maxLen, final boolean multiLine, final String posTxt, final String negTxt, final TextCallback callback) {
|
||||
Game.runOnRenderThread( new Callback() {
|
||||
|
|
|
@ -5,4 +5,6 @@ sourceCompatibility = targetCompatibility = appJavaCompatibility
|
|||
|
||||
dependencies {
|
||||
api project(':SPD-classes')
|
||||
//TODO might be nice to remove this, should decide
|
||||
implementation project(':services')
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.ui.LanguageButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.PrefsButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.StyledButton;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.UpdateNotification;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndStartGame;
|
||||
import com.watabou.glwrap.Blending;
|
||||
|
@ -225,6 +226,10 @@ public class TitleScene extends PixelScene {
|
|||
btnExit.setPos( w - btnExit.width(), 0 );
|
||||
add( btnExit );
|
||||
|
||||
UpdateNotification updInfo = new UpdateNotification();
|
||||
updInfo.setRect(4, h-BTN_HEIGHT, updInfo.reqWidth() + 6, BTN_HEIGHT-4);
|
||||
add(updInfo);
|
||||
|
||||
fadeIn();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
public class Updates {
|
||||
|
||||
public static UpdateService service;
|
||||
|
||||
public static boolean supportsUpdates(){
|
||||
return service != null;
|
||||
}
|
||||
|
||||
private static boolean updateChecked = false;
|
||||
|
||||
public static void checkForUpdate(){
|
||||
if (!supportsUpdates() || updateChecked) return;
|
||||
service.checkForUpdate(new UpdateService.UpdateResultCallback() {
|
||||
@Override
|
||||
public void onUpdateAvailable(AvailableUpdateData update) {
|
||||
updateChecked = true;
|
||||
updateData = update;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoUpdateFound() {
|
||||
updateChecked = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed() {
|
||||
updateChecked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void launchUpdate( AvailableUpdateData data ){
|
||||
service.initializeUpdate( data );
|
||||
}
|
||||
|
||||
private static AvailableUpdateData updateData = null;
|
||||
|
||||
public static boolean updateAvailable(){
|
||||
return updateData != null;
|
||||
}
|
||||
|
||||
public static AvailableUpdateData updateData(){
|
||||
return updateData;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.ui;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.AvailableUpdateData;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
|
||||
import com.watabou.noosa.Game;
|
||||
|
||||
public class UpdateNotification extends StyledButton {
|
||||
|
||||
private static AvailableUpdateData update;
|
||||
|
||||
public UpdateNotification(){
|
||||
super( Chrome.Type.GREY_BUTTON_TR, Messages.get(UpdateNotification.class, "title") );
|
||||
textColor( Window.SHPX_COLOR );
|
||||
visible = false;
|
||||
Updates.checkForUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
if (Updates.updateAvailable()){
|
||||
bg.alpha((float) (0.7f + Math.sin(Game.timeTotal*2)*0.3f));
|
||||
text.alpha((float) (0.7f + Math.sin(Game.timeTotal*2)*0.3f));
|
||||
visible = true;
|
||||
} else {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
update = Updates.updateData();
|
||||
ShatteredPixelDungeon.scene().addToFront( new WndUpdate() );
|
||||
}
|
||||
|
||||
public static class WndUpdate extends WndOptions {
|
||||
|
||||
public WndUpdate(){
|
||||
super(
|
||||
update.versionName == null ? Messages.get(WndUpdate.class,"title") : Messages.get(WndUpdate.class,"versioned_title", update.versionName),
|
||||
update.desc == null ? Messages.get(WndUpdate.class,"desc") : update.desc,
|
||||
Messages.get(WndUpdate.class,"button"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelect(int index) {
|
||||
if (index == 0) {
|
||||
Updates.launchUpdate(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
ui.quickslotbutton.select_item=Quickslot an item
|
||||
|
||||
ui.toolbar.examine_prompt=Press again to search\nPress a tile to examine
|
||||
|
||||
ui.updatenotification.title=Update
|
||||
ui.updatenotification$wndupdate.title=An Update is Available!
|
||||
ui.updatenotification$wndupdate.versioned_title=Update Available: %s
|
||||
ui.updatenotification$wndupdate.desc=Shattered Pixel Dungeon is regularly updated with overhauls to existing game content, or entirely new content!\n\nGame balance is also frequently improved in game updates, so that specific items/heroes/enemies aren't too strong or too weak.\n\nUpdates also include fixes for bugs and other various stability improvements.
|
||||
ui.updatenotification$wndupdate.button=Go To Update Page
|
|
@ -20,6 +20,10 @@ task debug(dependsOn: classes, type: JavaExec) {
|
|||
systemProperty 'Specification-Title', appName
|
||||
systemProperty 'Specification-Version', appVersionName + "-INDEV"
|
||||
systemProperty 'Implementation-Version', appVersionCode
|
||||
|
||||
dependencies {
|
||||
debugImplementation project(':services:updates:debugUpdates')
|
||||
}
|
||||
}
|
||||
|
||||
//need a separate task to compile dependencies first, seeing as we're setting them up in an odd way
|
||||
|
@ -38,6 +42,10 @@ task release(dependsOn: compileForRelease, type: Jar) {
|
|||
attributes 'Specification-Version': appVersionName
|
||||
attributes 'Implementation-Version': appVersionCode
|
||||
}
|
||||
|
||||
dependencies {
|
||||
releaseImplementation project(':services:updates:githubUpdates')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -47,4 +55,8 @@ dependencies {
|
|||
implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
|
||||
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
||||
implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
|
||||
|
||||
//Need these at compile time to prevent errors there.
|
||||
// The actual dependency used at runtime will vary based on source set.
|
||||
compileOnly project(':services:updates:debugUpdates')
|
||||
}
|
|
@ -29,6 +29,8 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Preferences;
|
|||
import com.badlogic.gdx.utils.SharedLibraryLoader;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.UpdateImpl;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.FileUtils;
|
||||
import com.watabou.utils.Point;
|
||||
|
@ -79,6 +81,10 @@ public class DesktopLauncher {
|
|||
} catch (NumberFormatException e) {
|
||||
Game.versionCode = Integer.parseInt(System.getProperty("Implementation-Version"));
|
||||
}
|
||||
|
||||
if (UpdateImpl.supportsUpdates()){
|
||||
Updates.service = UpdateImpl.getUpdateService();
|
||||
}
|
||||
|
||||
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
|
||||
|
||||
|
|
|
@ -58,6 +58,11 @@ public class DesktopPlatformSupport extends PlatformSupport {
|
|||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectedToUnmeteredNetwork() {
|
||||
return true; //no easy way to check this in desktop, just assume user doesn't care
|
||||
}
|
||||
|
||||
@Override
|
||||
public void promptTextInput(String title, String hintText, int maxLen, boolean multiLine, String posTxt, String negTxt, TextCallback callback) {
|
||||
|
||||
|
|
4
services/build.gradle
Normal file
4
services/build.gradle
Normal file
|
@ -0,0 +1,4 @@
|
|||
apply plugin: 'java-library'
|
||||
|
||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||
sourceCompatibility = targetCompatibility = appJavaCompatibility
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
public class AvailableUpdateData {
|
||||
|
||||
public String versionName;
|
||||
public int versionCode;
|
||||
|
||||
public String desc;
|
||||
|
||||
public String URL;
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
public abstract class UpdateService {
|
||||
|
||||
public static abstract class UpdateResultCallback {
|
||||
public abstract void onUpdateAvailable( AvailableUpdateData update );
|
||||
public abstract void onNoUpdateFound();
|
||||
public abstract void onConnectionFailed();
|
||||
}
|
||||
|
||||
public abstract void checkForUpdate( UpdateResultCallback callback );
|
||||
|
||||
public abstract void initializeUpdate( AvailableUpdateData update );
|
||||
|
||||
}
|
9
services/updates/debugUpdates/build.gradle
Normal file
9
services/updates/debugUpdates/build.gradle
Normal file
|
@ -0,0 +1,9 @@
|
|||
apply plugin: 'java-library'
|
||||
|
||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||
sourceCompatibility = targetCompatibility = appJavaCompatibility
|
||||
|
||||
dependencies {
|
||||
implementation project(':SPD-classes')
|
||||
api project(':services')
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
|
||||
public class DebugUpdates extends UpdateService {
|
||||
|
||||
private static AvailableUpdateData debugUpdateInfo;
|
||||
|
||||
@Override
|
||||
public void checkForUpdate(UpdateResultCallback callback) {
|
||||
|
||||
//turn on to test update UI
|
||||
if (false){
|
||||
debugUpdateInfo = new AvailableUpdateData();
|
||||
debugUpdateInfo.versionCode = Game.versionCode+1;
|
||||
debugUpdateInfo.URL = "http://www.google.com";
|
||||
|
||||
callback.onUpdateAvailable(debugUpdateInfo);
|
||||
} else {
|
||||
debugUpdateInfo = null;
|
||||
|
||||
callback.onNoUpdateFound();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUpdate(AvailableUpdateData update) {
|
||||
DeviceCompat.openURI( update.URL );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
public class UpdateImpl {
|
||||
|
||||
private static UpdateService updateChecker = new DebugUpdates();
|
||||
|
||||
public static UpdateService getUpdateService(){
|
||||
return updateChecker;
|
||||
}
|
||||
|
||||
public static boolean supportsUpdates(){
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
9
services/updates/githubUpdates/build.gradle
Normal file
9
services/updates/githubUpdates/build.gradle
Normal file
|
@ -0,0 +1,9 @@
|
|||
apply plugin: 'java-library'
|
||||
|
||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||
sourceCompatibility = targetCompatibility = appJavaCompatibility
|
||||
|
||||
dependencies {
|
||||
implementation project(':SPD-classes')
|
||||
api project(':services')
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Net;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.SSLProtocolException;
|
||||
|
||||
public class GitHubUpdates extends UpdateService {
|
||||
|
||||
private static Pattern descPattern = Pattern.compile("(.*?)(\r\n|\n|\r)(\r\n|\n|\r)---", Pattern.DOTALL + Pattern.MULTILINE);
|
||||
private static Pattern versionCodePattern = Pattern.compile("internal version number: ([0-9]*)", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
@Override
|
||||
public void checkForUpdate(UpdateResultCallback callback) {
|
||||
|
||||
if (!Game.platform.connectedToUnmeteredNetwork()){
|
||||
callback.onConnectionFailed();
|
||||
}
|
||||
|
||||
Net.HttpRequest httpGet = new Net.HttpRequest(Net.HttpMethods.GET);
|
||||
httpGet.setUrl("https://api.github.com/repos/00-Evan/shattered-pixel-dungeon/releases");
|
||||
httpGet.setHeader("Accept", "application/vnd.github.v3+json");
|
||||
|
||||
Gdx.net.sendHttpRequest(httpGet, new Net.HttpResponseListener() {
|
||||
@Override
|
||||
public void handleHttpResponse(Net.HttpResponse httpResponse) {
|
||||
try {
|
||||
Bundle latestRelease = null;
|
||||
int latestVersionCode = Game.versionCode;
|
||||
|
||||
boolean includePrereleases = Game.version.toLowerCase().contains("beta");
|
||||
|
||||
for (Bundle b : Bundle.read( httpResponse.getResultAsStream() ).getBundleArray()){
|
||||
Matcher m = versionCodePattern.matcher(b.getString("body"));
|
||||
|
||||
if (m.find()){
|
||||
int releaseVersion = Integer.parseInt(m.group(1));
|
||||
if (releaseVersion > latestVersionCode
|
||||
&& (includePrereleases || !b.getBoolean("prerelease"))){
|
||||
latestRelease = b;
|
||||
latestVersionCode = releaseVersion;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (latestRelease == null){
|
||||
callback.onNoUpdateFound();
|
||||
} else {
|
||||
|
||||
AvailableUpdateData update = new AvailableUpdateData();
|
||||
|
||||
update.versionName = latestRelease.getString("name");
|
||||
update.versionCode = latestVersionCode;
|
||||
Matcher m = descPattern.matcher(latestRelease.getString("body"));
|
||||
m.find();
|
||||
update.desc = m.group(1);
|
||||
update.URL = latestRelease.getString("html_url");
|
||||
|
||||
callback.onUpdateAvailable(update);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Game.reportException( e );
|
||||
callback.onConnectionFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable t) {
|
||||
//Failure in SSL handshake, possibly because GitHub requires TLS 1.2+.
|
||||
// Often happens for old OS versions with outdated security protocols.
|
||||
// Future update attempts won't work anyway, so just pretend nothing was found.
|
||||
if (t instanceof SSLProtocolException){
|
||||
callback.onNoUpdateFound();
|
||||
} else {
|
||||
Game.reportException(t);
|
||||
callback.onConnectionFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelled() {
|
||||
callback.onConnectionFailed();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeUpdate(AvailableUpdateData update) {
|
||||
DeviceCompat.openURI( update.URL );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2019 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.services.updates;
|
||||
|
||||
public class UpdateImpl {
|
||||
|
||||
private static UpdateService updateChecker = new GitHubUpdates();
|
||||
|
||||
public static UpdateService getUpdateService(){
|
||||
return updateChecker;
|
||||
}
|
||||
|
||||
public static boolean supportsUpdates(){
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
include ':core', ':SPD-classes', ':android', ':desktop'
|
||||
include ':core', ':SPD-classes', ':android', ':desktop', ':services',
|
||||
':services:updates:debugUpdates', ':services:updates:githubUpdates'
|
Loading…
Reference in New Issue
Block a user