v0.8.0: added an update notification service

This commit is contained in:
Evan Debenham 2019-11-22 15:05:47 -05:00
parent 2e533b74db
commit 2138ad24ec
24 changed files with 606 additions and 13 deletions

View File

@ -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();

View File

@ -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

View File

@ -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')
}
}
}

View File

@ -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.-->

View File

@ -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

View File

@ -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() {

View File

@ -5,4 +5,6 @@ sourceCompatibility = targetCompatibility = appJavaCompatibility
dependencies {
api project(':SPD-classes')
//TODO might be nice to remove this, should decide
implementation project(':services')
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}
}

View File

@ -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

View File

@ -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')
}

View File

@ -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();

View File

@ -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
View File

@ -0,0 +1,4 @@
apply plugin: 'java-library'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
sourceCompatibility = targetCompatibility = appJavaCompatibility

View File

@ -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;
}

View File

@ -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 );
}

View 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')
}

View File

@ -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 );
}
}

View File

@ -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;
}
}

View 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')
}

View File

@ -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 );
}
}

View File

@ -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;
}
}

View File

@ -1 +1,2 @@
include ':core', ':SPD-classes', ':android', ':desktop'
include ':core', ':SPD-classes', ':android', ':desktop', ':services',
':services:updates:debugUpdates', ':services:updates:githubUpdates'