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;
}
// 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.
String modules = ProjectSettings::get_singleton()->get("android/modules");
if (modules.find("org/godotengine/godot/GodotPaymentV3") != -1) {
bool godot_payment_enabled = p_preset->get("plugins/" + GODOT_PAYMENT.name);
if (!godot_payment_enabled) {
bool godot_google_play_billing_enabled = p_preset->get("plugins/GodotGooglePlayBilling");
if (!godot_google_play_billing_enabled) {
valid = false;
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"
"Note that the singleton was also renamed from \"GodotPayments\" to \"GodotPayment\".");
"Replace it with the first-party \"GodotGooglePlayBilling\" plugin.\n"
"Note that the singleton was also renamed from \"GodotPayments\" to \"GodotGooglePlayBilling\".");
err += "\n";
}
}

View file

@ -97,13 +97,6 @@ task copyReleaseAARToAppModule(type: Copy) {
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.
* 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'
}

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.
* Currently unused, this is just for future reference:
*/
static const PluginConfig GODOT_PAYMENT = {
/*.valid_config =*/true,
/*.last_updated =*/0,
/*.name =*/"GodotPayment",
/*.binary_type =*/"local",
/*.binary =*/"res://android/build/libs/plugins/GodotPayment.release.aar",
/*.local_dependencies =*/{},
/*.remote_dependencies =*/String("com.android.billingclient:billing:2.2.1").split("|"),
/*.custom_maven_repos =*/{}
};
// static const PluginConfig MY_PREBUILT_PLUGIN = {
// /*.valid_config =*/true,
// /*.last_updated =*/0,
// /*.name =*/"GodotPayment",
// /*.binary_type =*/"local",
// /*.binary =*/"res://android/build/libs/plugins/GodotPayment.release.aar",
// /*.local_dependencies =*/{},
// /*.remote_dependencies =*/String("com.android.billingclient:billing:2.2.1").split("|"),
// /*.custom_maven_repos =*/{}
// };
static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_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) {
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;
}