diff --git a/android/build.gradle b/android/build.gradle index 298d8947a..6888df33c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -27,6 +27,7 @@ android { versionNameSuffix '-INDEV' dependencies { debugImplementation project(':services:updates:debugUpdates') + debugImplementation project(':services:news:debugNews') } } release { @@ -41,6 +42,7 @@ android { dependencies { releaseImplementation project(':services:updates:githubUpdates') + releaseImplementation project(':services:news:shatteredNews') } } } diff --git a/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidGame.java b/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidGame.java index 0b92bbe00..ed494884f 100644 --- a/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidGame.java +++ b/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidGame.java @@ -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.news.News; +import com.shatteredpixel.shatteredpixeldungeon.services.news.NewsImpl; import com.shatteredpixel.shatteredpixeldungeon.services.updates.UpdateImpl; import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates; import com.watabou.noosa.Game; @@ -60,10 +62,13 @@ public class AndroidGame extends AndroidApplication { } catch (PackageManager.NameNotFoundException e) { Game.versionCode = 0; } - + if (UpdateImpl.supportsUpdates()){ Updates.service = UpdateImpl.getUpdateService(); } + if (NewsImpl.supportsNews()){ + News.service = NewsImpl.getNewsService(); + } FileUtils.setDefaultFileProperties( Files.FileType.Local, "" ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/News.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/News.java new file mode 100644 index 000000000..748cbd6b9 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/News.java @@ -0,0 +1,78 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +import java.util.ArrayList; +import java.util.Date; + +public class News { + + public static NewsService service; + + public static boolean supportsNews(){ + return service != null; + } + + private static Date lastCheck = null; + private static final long CHECK_DELAY = 1000*60*60; //1 hour + + public static void checkForNews(){ + if (!supportsNews()) return; + if (lastCheck != null && (new Date().getTime() - lastCheck.getTime()) < CHECK_DELAY) return; + + service.checkForArticles(new NewsService.NewsResultCallback() { + @Override + public void onArticlesFound(ArrayList articles) { + lastCheck = new Date(); + News.articles = articles; + } + + @Override + public void onConnectionFailed() { + lastCheck = null; + News.articles = null; + } + }); + + } + + private static ArrayList articles; + + public static boolean articlesAvailable(){ + return articles != null; + } + + public static ArrayList articles(){ + return articles; + } + + public static int unreadArticles(Date lastRead){ + int unread = 0; + for (NewsArticle article : articles){ + if (article.date.after(lastRead)) unread++; + } + return unread; + } + + + +} diff --git a/desktop/build.gradle b/desktop/build.gradle index 74eea650a..75337e980 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -23,6 +23,7 @@ task debug(dependsOn: classes, type: JavaExec) { dependencies { debugImplementation project(':services:updates:debugUpdates') + debugImplementation project(':services:news:debugNews') } } @@ -45,6 +46,7 @@ task release(dependsOn: compileForRelease, type: Jar) { dependencies { releaseImplementation project(':services:updates:githubUpdates') + releaseImplementation project(':services:news:shatteredNews') } } @@ -65,4 +67,5 @@ dependencies { //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') + compileOnly project(':services:news:debugNews') } \ No newline at end of file diff --git a/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopLauncher.java b/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopLauncher.java index 103b0f6b5..37ccf0b50 100644 --- a/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopLauncher.java +++ b/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopLauncher.java @@ -31,6 +31,8 @@ import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.SharedLibraryLoader; import com.shatteredpixel.shatteredpixeldungeon.SPDSettings; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.services.news.News; +import com.shatteredpixel.shatteredpixeldungeon.services.news.NewsImpl; import com.shatteredpixel.shatteredpixeldungeon.services.updates.UpdateImpl; import com.shatteredpixel.shatteredpixeldungeon.services.updates.Updates; import com.watabou.noosa.Game; @@ -98,6 +100,9 @@ public class DesktopLauncher { if (UpdateImpl.supportsUpdates()){ Updates.service = UpdateImpl.getUpdateService(); } + if (NewsImpl.supportsNews()){ + News.service = NewsImpl.getNewsService(); + } Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); diff --git a/services/news/debugNews/build.gradle b/services/news/debugNews/build.gradle new file mode 100644 index 000000000..f3ef39c91 --- /dev/null +++ b/services/news/debugNews/build.gradle @@ -0,0 +1,30 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +apply plugin: 'java-library' + +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +sourceCompatibility = targetCompatibility = appJavaCompatibility + +dependencies { + implementation project(':SPD-classes') + api project(':services') +} diff --git a/services/news/debugNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/DebugNews.java b/services/news/debugNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/DebugNews.java new file mode 100644 index 000000000..3b6dcd3ac --- /dev/null +++ b/services/news/debugNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/DebugNews.java @@ -0,0 +1,59 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; + +public class DebugNews extends NewsService { + + @Override + public void checkForArticles(NewsResultCallback callback) { + + //turn on to test connection failure + if (false){ + callback.onConnectionFailed(); + return; + } + + ArrayList articles = new ArrayList<>(); + for (int i = 0; i < 10; i++){ + NewsArticle article = new NewsArticle(); + article.title = "TEST ARTICLE " + i; + article.summary = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " + + "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " + + "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + + "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit " + + "esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat " + + "non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; + article.URL = "http://www.google.com"; + // a year in the past, plus one day for each article + long daysBack = 365+i; + article.date = new Date(System.currentTimeMillis() - (daysBack*1000*60*60*24)); + articles.add(article); + } + + callback.onArticlesFound(articles); + + } +} diff --git a/services/news/debugNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsImpl.java b/services/news/debugNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsImpl.java new file mode 100644 index 000000000..fc99ae21b --- /dev/null +++ b/services/news/debugNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsImpl.java @@ -0,0 +1,36 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +public class NewsImpl { + + private static NewsService newsChecker = new DebugNews(); + + public static NewsService getNewsService(){ + return newsChecker; + } + + public static boolean supportsNews(){ + return true; + } + +} diff --git a/services/news/shatteredNews/build.gradle b/services/news/shatteredNews/build.gradle new file mode 100644 index 000000000..f3ef39c91 --- /dev/null +++ b/services/news/shatteredNews/build.gradle @@ -0,0 +1,30 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +apply plugin: 'java-library' + +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +sourceCompatibility = targetCompatibility = appJavaCompatibility + +dependencies { + implementation project(':SPD-classes') + api project(':services') +} diff --git a/services/news/shatteredNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsImpl.java b/services/news/shatteredNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsImpl.java new file mode 100644 index 000000000..e74931f7d --- /dev/null +++ b/services/news/shatteredNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsImpl.java @@ -0,0 +1,36 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +public class NewsImpl { + + private static NewsService newsChecker = new ShatteredNews(); + + public static NewsService getNewsService(){ + return newsChecker; + } + + public static boolean supportsNews(){ + return true; + } + +} \ No newline at end of file diff --git a/services/news/shatteredNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/ShatteredNews.java b/services/news/shatteredNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/ShatteredNews.java new file mode 100644 index 000000000..69fa86470 --- /dev/null +++ b/services/news/shatteredNews/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/ShatteredNews.java @@ -0,0 +1,82 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Net; +import com.badlogic.gdx.utils.XmlReader; +import com.watabou.noosa.Game; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Locale; + +public class ShatteredNews extends NewsService { + + @Override + public void checkForArticles(NewsResultCallback callback) { + + if (!Game.platform.connectedToUnmeteredNetwork()){ + callback.onConnectionFailed(); + } + + Net.HttpRequest httpGet = new Net.HttpRequest(Net.HttpMethods.GET); + httpGet.setUrl("http://shatteredpixel.com/feed"); + + Gdx.net.sendHttpRequest(httpGet, new Net.HttpResponseListener() { + @Override + public void handleHttpResponse(Net.HttpResponse httpResponse) { + ArrayList articles = new ArrayList<>(); + XmlReader reader = new XmlReader(); + XmlReader.Element xmlDoc = reader.parse(httpResponse.getResultAsStream()); + + SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); + + for (XmlReader.Element xmlArticle : xmlDoc.getChildrenByName("entry")){ + NewsArticle article = new NewsArticle(); + article.title = xmlArticle.get("title"); + try { + article.date = dateParser.parse(xmlArticle.get("published")); + } catch (ParseException e) { + Game.reportException(e); + } + article.summary = xmlArticle.get("summary"); + article.URL = xmlArticle.get("id").replace("https://", "http://"); + articles.add(article); + } + callback.onArticlesFound(articles); + } + + @Override + public void failed(Throwable t) { + callback.onConnectionFailed(); + } + + @Override + public void cancelled() { + callback.onConnectionFailed(); + } + }); + } + +} diff --git a/services/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsArticle.java b/services/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsArticle.java new file mode 100644 index 000000000..6702d59ba --- /dev/null +++ b/services/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsArticle.java @@ -0,0 +1,33 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +import java.util.Date; + +public class NewsArticle { + + public String title; + public String summary; + public String URL; + public Date date; + +} diff --git a/services/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsService.java b/services/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsService.java new file mode 100644 index 000000000..e950e40ae --- /dev/null +++ b/services/src/main/java/com/shatteredpixel/shatteredpixeldungeon/services/news/NewsService.java @@ -0,0 +1,35 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2020 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.services.news; + +import java.util.ArrayList; + +public abstract class NewsService { + + public static abstract class NewsResultCallback { + public abstract void onArticlesFound(ArrayList articles); + public abstract void onConnectionFailed(); + } + + public abstract void checkForArticles( NewsResultCallback callback ); + +} diff --git a/settings.gradle b/settings.gradle index 8c9a768e1..06010c0cf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ include ':core', ':SPD-classes', ':android', ':desktop', ':services', - ':services:updates:debugUpdates', ':services:updates:githubUpdates' \ No newline at end of file + ':services:updates:debugUpdates', ':services:updates:githubUpdates', + ':services:news:debugNews', ':services:news:shatteredNews' \ No newline at end of file