Remove GodotPayment android plugin

This is now available in a separate repository
at https://github.com/godotengine/godot-google-play-billing
This commit is contained in:
Timo Schwarzer 2020-06-22 09:17:26 +02:00
parent 000db65d40
commit 5053ab684a
No known key found for this signature in database
GPG Key ID: C4062DA320280737
8 changed files with 17 additions and 373 deletions

View File

@ -1911,16 +1911,16 @@ public:
err += etc_error; err += etc_error;
} }
// The GodotPaymentV3 module was converted to the GodotPayment plugin in Godot 3.2.2, // The GodotPaymentV3 module was converted to the external GodotGooglePlayBilling plugin in Godot 3.2.2,
// this check helps users to notice the change to ensure that they change their settings. // this check helps users to notice the change to ensure that they change their settings.
String modules = ProjectSettings::get_singleton()->get("android/modules"); String modules = ProjectSettings::get_singleton()->get("android/modules");
if (modules.find("org/godotengine/godot/GodotPaymentV3") != -1) { if (modules.find("org/godotengine/godot/GodotPaymentV3") != -1) {
bool godot_payment_enabled = p_preset->get("plugins/" + GODOT_PAYMENT.name); bool godot_google_play_billing_enabled = p_preset->get("plugins/GodotGooglePlayBilling");
if (!godot_payment_enabled) { if (!godot_google_play_billing_enabled) {
valid = false; valid = false;
err += TTR("Invalid \"GodotPaymentV3\" module included in the \"android/modules\" project setting (changed in Godot 3.2.2).\n" err += TTR("Invalid \"GodotPaymentV3\" module included in the \"android/modules\" project setting (changed in Godot 3.2.2).\n"
"Replace it by the \"GodotPayment\" plugin, which should be enabled in the \"Plugins\" preset section.\n" "Replace it with the first-party \"GodotGooglePlayBilling\" plugin.\n"
"Note that the singleton was also renamed from \"GodotPayments\" to \"GodotPayment\"."); "Note that the singleton was also renamed from \"GodotPayments\" to \"GodotGooglePlayBilling\".");
err += "\n"; err += "\n";
} }
} }

View File

@ -97,13 +97,6 @@ task copyReleaseAARToAppModule(type: Copy) {
include('godot-lib.release.aar') include('godot-lib.release.aar')
} }
task copyGodotPaymentPluginToAppModule(type: Copy) {
dependsOn ':plugins:godotpayment:assembleRelease'
from('plugins/godotpayment/build/outputs/aar')
into('app/libs/plugins')
include('GodotPayment.release.aar')
}
/** /**
* Copy the Godot android library archive release file into the root bin directory. * Copy the Godot android library archive release file into the root bin directory.
* Depends on the library build task to ensure the AAR file is generated prior to copying. * Depends on the library build task to ensure the AAR file is generated prior to copying.
@ -161,7 +154,6 @@ task generateGodotTemplates(type: GradleBuild) {
} }
} }
dependsOn 'copyGodotPaymentPluginToAppModule'
finalizedBy 'zipCustomBuild' finalizedBy 'zipCustomBuild'
} }

View File

View File

@ -1,32 +0,0 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
libraryVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "GodotPayment.${variant.name}.aar"
}
}
}
dependencies {
implementation libraries.supportCoreUtils
implementation libraries.v4Support
implementation 'com.android.billingclient:billing:2.2.1'
if (rootProject.findProject(":lib")) {
compileOnly project(":lib")
} else if (rootProject.findProject(":godot:lib")) {
compileOnly project(":godot:lib")
} else {
compileOnly fileTree(dir: 'libs', include: ['godot-lib*.aar'])
}
}

View File

@ -1,11 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.godotengine.godot.plugin.payment">
<application>
<meta-data
android:name="org.godotengine.plugin.v1.GodotPayment"
android:value="org.godotengine.godot.plugin.payment.GodotPayment" />
</application>
</manifest>

View File

@ -1,240 +0,0 @@
/*************************************************************************/
/* GodotPayment.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
package org.godotengine.godot.plugin.payment;
import org.godotengine.godot.Dictionary;
import org.godotengine.godot.Godot;
import org.godotengine.godot.plugin.GodotPlugin;
import org.godotengine.godot.plugin.SignalInfo;
import org.godotengine.godot.plugin.payment.utils.GodotPaymentUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.ArraySet;
import com.android.billingclient.api.AcknowledgePurchaseParams;
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class GodotPayment extends GodotPlugin implements PurchasesUpdatedListener, BillingClientStateListener {
private final BillingClient billingClient;
private final HashMap<String, SkuDetails> skuDetailsCache = new HashMap<>(); // sku SkuDetails
public GodotPayment(Godot godot) {
super(godot);
billingClient = BillingClient
.newBuilder(getActivity())
.enablePendingPurchases()
.setListener(this)
.build();
}
public void startConnection() {
billingClient.startConnection(this);
}
public void endConnection() {
billingClient.endConnection();
}
public boolean isReady() {
return this.billingClient.isReady();
}
public Dictionary queryPurchases(String type) {
Purchase.PurchasesResult result = billingClient.queryPurchases(type);
Dictionary returnValue = new Dictionary();
if (result.getBillingResult().getResponseCode() == BillingClient.BillingResponseCode.OK) {
returnValue.put("status", 0); // OK = 0
returnValue.put("purchases", GodotPaymentUtils.convertPurchaseListToDictionaryObjectArray(result.getPurchasesList()));
} else {
returnValue.put("status", 1); // FAILED = 1
returnValue.put("response_code", result.getBillingResult().getResponseCode());
returnValue.put("debug_message", result.getBillingResult().getDebugMessage());
}
return returnValue;
}
public void querySkuDetails(final String[] list, String type) {
List<String> skuList = Arrays.asList(list);
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder()
.setSkusList(skuList)
.setType(type);
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult,
List<SkuDetails> skuDetailsList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (SkuDetails skuDetails : skuDetailsList) {
skuDetailsCache.put(skuDetails.getSku(), skuDetails);
}
emitSignal("sku_details_query_completed", (Object)GodotPaymentUtils.convertSkuDetailsListToDictionaryObjectArray(skuDetailsList));
} else {
emitSignal("sku_details_query_error", billingResult.getResponseCode(), billingResult.getDebugMessage(), list);
}
}
});
}
public void acknowledgePurchase(final String purchaseToken) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchaseToken)
.build();
billingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
@Override
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
emitSignal("purchase_acknowledged", purchaseToken);
} else {
emitSignal("purchase_acknowledgement_error", billingResult.getResponseCode(), billingResult.getDebugMessage(), purchaseToken);
}
}
});
}
public void consumePurchase(String purchaseToken) {
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchaseToken)
.build();
billingClient.consumeAsync(consumeParams, new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
emitSignal("purchase_consumed", purchaseToken);
} else {
emitSignal("purchase_consumption_error", billingResult.getResponseCode(), billingResult.getDebugMessage(), purchaseToken);
}
}
});
}
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
emitSignal("connected");
} else {
emitSignal("connect_error", billingResult.getResponseCode(), billingResult.getDebugMessage());
}
}
@Override
public void onBillingServiceDisconnected() {
emitSignal("disconnected");
}
public Dictionary purchase(String sku) {
if (!skuDetailsCache.containsKey(sku)) {
emitSignal("purchase_error", null, "You must query the sku details and wait for the result before purchasing!");
}
SkuDetails skuDetails = skuDetailsCache.get(sku);
BillingFlowParams purchaseParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
BillingResult result = billingClient.launchBillingFlow(getActivity(), purchaseParams);
Dictionary returnValue = new Dictionary();
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
returnValue.put("status", 0); // OK = 0
} else {
returnValue.put("status", 1); // FAILED = 1
returnValue.put("response_code", result.getResponseCode());
returnValue.put("debug_message", result.getDebugMessage());
}
return returnValue;
}
@Override
public void onPurchasesUpdated(final BillingResult billingResult, @Nullable final List<Purchase> list) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
emitSignal("purchases_updated", (Object)GodotPaymentUtils.convertPurchaseListToDictionaryObjectArray(list));
} else {
emitSignal("purchase_error", billingResult.getResponseCode(), billingResult.getDebugMessage());
}
}
@NonNull
@Override
public String getPluginName() {
return "GodotPayment";
}
@NonNull
@Override
public List<String> getPluginMethods() {
return Arrays.asList("startConnection", "endConnection", "purchase", "querySkuDetails", "isReady", "queryPurchases", "acknowledgePurchase", "consumePurchase");
}
@NonNull
@Override
public Set<SignalInfo> getPluginSignals() {
Set<SignalInfo> signals = new ArraySet<>();
signals.add(new SignalInfo("connected"));
signals.add(new SignalInfo("disconnected"));
signals.add(new SignalInfo("connect_error", Integer.class, String.class));
signals.add(new SignalInfo("purchases_updated", Object[].class));
signals.add(new SignalInfo("purchase_error", Integer.class, String.class));
signals.add(new SignalInfo("sku_details_query_completed", Object[].class));
signals.add(new SignalInfo("sku_details_query_error", Integer.class, String.class, String[].class));
signals.add(new SignalInfo("purchase_acknowledged", String.class));
signals.add(new SignalInfo("purchase_acknowledgement_error", Integer.class, String.class, String.class));
signals.add(new SignalInfo("purchase_consumed", String.class));
signals.add(new SignalInfo("purchase_consumption_error", Integer.class, String.class, String.class));
return signals;
}
}

View File

@ -1,66 +0,0 @@
package org.godotengine.godot.plugin.payment.utils;
import org.godotengine.godot.Dictionary;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.SkuDetails;
import java.util.List;
public class GodotPaymentUtils {
public static Dictionary convertPurchaseToDictionary(Purchase purchase) {
Dictionary dictionary = new Dictionary();
dictionary.put("order_id", purchase.getOrderId());
dictionary.put("package_name", purchase.getPackageName());
dictionary.put("purchase_state", Integer.valueOf(purchase.getPurchaseState()));
dictionary.put("purchase_time", Long.valueOf(purchase.getPurchaseTime()));
dictionary.put("purchase_token", purchase.getPurchaseToken());
dictionary.put("signature", purchase.getSignature());
dictionary.put("sku", purchase.getSku());
dictionary.put("is_acknowledged", Boolean.valueOf(purchase.isAcknowledged()));
dictionary.put("is_auto_renewing", Boolean.valueOf(purchase.isAutoRenewing()));
return dictionary;
}
public static Dictionary convertSkuDetailsToDictionary(SkuDetails details) {
Dictionary dictionary = new Dictionary();
dictionary.put("sku", details.getSku());
dictionary.put("title", details.getTitle());
dictionary.put("description", details.getDescription());
dictionary.put("price", details.getPrice());
dictionary.put("price_currency_code", details.getPriceCurrencyCode());
dictionary.put("price_amount_micros", Long.valueOf(details.getPriceAmountMicros()));
dictionary.put("free_trial_period", details.getFreeTrialPeriod());
dictionary.put("icon_url", details.getIconUrl());
dictionary.put("introductory_price", details.getIntroductoryPrice());
dictionary.put("introductory_price_amount_micros", Long.valueOf(details.getIntroductoryPriceAmountMicros()));
dictionary.put("introductory_price_cycles", details.getIntroductoryPriceCycles());
dictionary.put("introductory_price_period", details.getIntroductoryPricePeriod());
dictionary.put("original_price", details.getOriginalPrice());
dictionary.put("original_price_amount_micros", Long.valueOf(details.getOriginalPriceAmountMicros()));
dictionary.put("subscription_period", details.getSubscriptionPeriod());
dictionary.put("type", details.getType());
dictionary.put("is_rewarded", Boolean.valueOf(details.isRewarded()));
return dictionary;
}
public static Object[] convertPurchaseListToDictionaryObjectArray(List<Purchase> purchases) {
Object[] purchaseDictionaries = new Object[purchases.size()];
for (int i = 0; i < purchases.size(); i++) {
purchaseDictionaries[i] = GodotPaymentUtils.convertPurchaseToDictionary(purchases.get(i));
}
return purchaseDictionaries;
}
public static Object[] convertSkuDetailsListToDictionaryObjectArray(List<SkuDetails> skuDetails) {
Object[] skuDetailsDictionaries = new Object[skuDetails.size()];
for (int i = 0; i < skuDetails.size(); i++) {
skuDetailsDictionaries[i] = GodotPaymentUtils.convertSkuDetailsToDictionary(skuDetails.get(i));
}
return skuDetailsDictionaries;
}
}

View File

@ -86,17 +86,18 @@ struct PluginConfig {
/* /*
* Set of prebuilt plugins. * Set of prebuilt plugins.
* Currently unused, this is just for future reference:
*/ */
static const PluginConfig GODOT_PAYMENT = { // static const PluginConfig MY_PREBUILT_PLUGIN = {
/*.valid_config =*/true, // /*.valid_config =*/true,
/*.last_updated =*/0, // /*.last_updated =*/0,
/*.name =*/"GodotPayment", // /*.name =*/"GodotPayment",
/*.binary_type =*/"local", // /*.binary_type =*/"local",
/*.binary =*/"res://android/build/libs/plugins/GodotPayment.release.aar", // /*.binary =*/"res://android/build/libs/plugins/GodotPayment.release.aar",
/*.local_dependencies =*/{}, // /*.local_dependencies =*/{},
/*.remote_dependencies =*/String("com.android.billingclient:billing:2.2.1").split("|"), // /*.remote_dependencies =*/String("com.android.billingclient:billing:2.2.1").split("|"),
/*.custom_maven_repos =*/{} // /*.custom_maven_repos =*/{}
}; // };
static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) { static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
String absolute_path; String absolute_path;
@ -125,7 +126,7 @@ static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin,
static inline Vector<PluginConfig> get_prebuilt_plugins(String plugins_base_dir) { static inline Vector<PluginConfig> get_prebuilt_plugins(String plugins_base_dir) {
Vector<PluginConfig> prebuilt_plugins; Vector<PluginConfig> prebuilt_plugins;
prebuilt_plugins.push_back(resolve_prebuilt_plugin(GODOT_PAYMENT, plugins_base_dir)); // prebuilt_plugins.push_back(resolve_prebuilt_plugin(MY_PREBUILT_PLUGIN, plugins_base_dir));
return prebuilt_plugins; return prebuilt_plugins;
} }