diff --git a/README.md b/README.md index bdf03a0..58826ad 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ isn't quite there yet. At the time of writing, the following are implemented. ### Ecom interface - Catalog offers (query/count/copy) +- Entitlements (query/count/copy) If there's something missing that you need, please do open an issue. PRs are very welcome. diff --git a/jni/cpp/jni_utils.cpp b/jni/cpp/jni_utils.cpp index c1cec40..6574156 100644 --- a/jni/cpp/jni_utils.cpp +++ b/jni/cpp/jni_utils.cpp @@ -95,6 +95,13 @@ jint EOS4J::javaEnumValueFromObject(JNIEnv* env, jobject obj) { return env->CallIntMethod(obj, ord); } +jboolean +EOS4J::javaBooleanFromObjectField(JNIEnv* env, jobject obj, const char* field) { + jclass cls = env->GetObjectClass(obj); + jfieldID fid = env->GetFieldID(cls, field, "Z"); + return env->GetBooleanField(obj, fid); +} + void EOS4J::throwEOSException(JNIEnv* env, int result_code) { jclass cls = env->FindClass("com/bearwaves/eos4j/EOSException"); jmethodID ctor = env->GetMethodID(cls, "", "(I)V"); diff --git a/jni/cpp/jni_utils.h b/jni/cpp/jni_utils.h index 701fcda..35f8891 100644 --- a/jni/cpp/jni_utils.h +++ b/jni/cpp/jni_utils.h @@ -45,6 +45,9 @@ jlong javaLongFromObjectField(JNIEnv* env, jobject obj, const char* field); jint javaEnumValueFromObject(JNIEnv* env, jobject obj); +jboolean +javaBooleanFromObjectField(JNIEnv* env, jobject obj, const char* field); + void throwEOSException(JNIEnv* env, int result_code); } // namespace EOS4J \ No newline at end of file diff --git a/src/main/java/com/bearwaves/eos4j/EOSEcom.java b/src/main/java/com/bearwaves/eos4j/EOSEcom.java index 497d0bc..26cfab5 100644 --- a/src/main/java/com/bearwaves/eos4j/EOSEcom.java +++ b/src/main/java/com/bearwaves/eos4j/EOSEcom.java @@ -26,6 +26,30 @@ public CatalogOffer copyOfferById(CopyOfferByIdOptions options) throws EOSExcept return EOSEcomNative.copyOfferById(handle, options); } + public void queryEntitlements(QueryEntitlementsOptions options, OnQueryEntitlementsCallback callback) { + EOSEcomNative.queryEntitlements(handle, options, callback); + } + + public int getEntitlementsCount(GetEntitlementsCountOptions options) { + return EOSEcomNative.getEntitlementsCount(handle, options); + } + + public int getEntitlementsByNameCount(GetEntitlementsByNameCountOptions options) { + return EOSEcomNative.getEntitlementsByNameCount(handle, options); + } + + public Entitlement copyEntitlementByIndex(CopyEntitlementByIndexOptions options) throws EOSException { + return EOSEcomNative.copyEntitlementByIndex(handle, options); + } + + public Entitlement copyEntitlementById(CopyEntitlementByIdOptions options) throws EOSException { + return EOSEcomNative.copyEntitlementById(handle, options); + } + + public Entitlement copyEntitlementByNameAndIndex(CopyEntitlementByNameAndIndexOptions options) throws EOSException { + return EOSEcomNative.copyEntitlementByNameAndIndex(handle, options); + } + public static class CatalogOffer extends EOSHandle { public final int serverIndex; public final String catalogNamespace; @@ -88,6 +112,35 @@ public void release() { } } + public static class Entitlement extends EOSHandle { + public final String entitlementName; + public final String entitlementId; + public final String catalogItemId; + public final int serverIndex; + public final boolean redeemed; + public final Date end; + + public Entitlement(long ptr, + String entitlementName, + String entitlementId, + String catalogItemId, + int serverIndex, + boolean redeemed, + Date end) { + super(ptr); + this.entitlementName = entitlementName; + this.entitlementId = entitlementId; + this.catalogItemId = catalogItemId; + this.serverIndex = serverIndex; + this.redeemed = redeemed; + this.end = end; + } + + public void release() { + EOSEcomNative.releaseEntitlement(ptr); + } + } + public static class QueryOffersOptions { public final EOS.EpicAccountId localUserId; public final String overrideCatalogNamespace; @@ -126,6 +179,68 @@ public CopyOfferByIdOptions(EOS.EpicAccountId localUserId, String offerId) { } } + public static class QueryEntitlementsOptions { + public final EOS.EpicAccountId localUserId; + public final String[] entitlementNames; + public final boolean includeRedeemed; + + public QueryEntitlementsOptions(EOS.EpicAccountId localUserId, String[] entitlementNames, boolean includeRedeemed) { + this.localUserId = localUserId; + this.entitlementNames = entitlementNames; + this.includeRedeemed = includeRedeemed; + } + } + + public static class GetEntitlementsCountOptions { + public final EOS.EpicAccountId localUserId; + + public GetEntitlementsCountOptions(EOS.EpicAccountId localUserId) { + this.localUserId = localUserId; + } + } + + public static class GetEntitlementsByNameCountOptions { + public final EOS.EpicAccountId localUserId; + public final String entitlementName; + + public GetEntitlementsByNameCountOptions(EOS.EpicAccountId localUserId, String entitlementName) { + this.localUserId = localUserId; + this.entitlementName = entitlementName; + } + } + + public static class CopyEntitlementByIndexOptions { + public final EOS.EpicAccountId localUserId; + public final int entitlementIndex; + + public CopyEntitlementByIndexOptions(EOS.EpicAccountId localUserId, int entitlementIndex) { + this.localUserId = localUserId; + this.entitlementIndex = entitlementIndex; + } + } + + public static class CopyEntitlementByIdOptions { + public final EOS.EpicAccountId localUserId; + public final String entitlementId; + + public CopyEntitlementByIdOptions(EOS.EpicAccountId localUserId, String entitlementId) { + this.localUserId = localUserId; + this.entitlementId = entitlementId; + } + } + + public static class CopyEntitlementByNameAndIndexOptions { + public final EOS.EpicAccountId localUserId; + public final String entitlementName; + public final int index; + + public CopyEntitlementByNameAndIndexOptions(EOS.EpicAccountId localUserId, String entitlementName, int index) { + this.localUserId = localUserId; + this.entitlementName = entitlementName; + this.index = index; + } + } + public static class QueryOffersCallbackInfo { public final int resultCode; public final EOS.EpicAccountId localUserId; @@ -136,7 +251,21 @@ public QueryOffersCallbackInfo(int resultCode, EOS.EpicAccountId localUserId) { } } + public static class QueryEntitlementsCallbackInfo { + public final int resultCode; + public final EOS.EpicAccountId localUserId; + + public QueryEntitlementsCallbackInfo(int resultCode, EOS.EpicAccountId localUserId) { + this.resultCode = resultCode; + this.localUserId = localUserId; + } + } + public interface OnQueryOffersCompleteCallback { void run(QueryOffersCallbackInfo data); } + + public interface OnQueryEntitlementsCallback { + void run(QueryEntitlementsCallbackInfo data); + } } diff --git a/src/main/java/com/bearwaves/eos4j/EOSEcomNative.java b/src/main/java/com/bearwaves/eos4j/EOSEcomNative.java index da040f3..c789be1 100644 --- a/src/main/java/com/bearwaves/eos4j/EOSEcomNative.java +++ b/src/main/java/com/bearwaves/eos4j/EOSEcomNative.java @@ -161,5 +161,197 @@ static native EOSEcom.CatalogOffer copyOfferById( static native void releaseCatalogOffer(long handle); /* EOS_Ecom_CatalogOffer_Release(reinterpret_cast(handle)); */ + + static native void queryEntitlements( + long handle, EOSEcom.QueryEntitlementsOptions options, EOSEcom.OnQueryEntitlementsCallback callback + ); /* + jobject local_user_id_obj = EOS4J::javaObjectFromObjectField(env, options, "localUserId", "Lcom/bearwaves/eos4j/EOS$EpicAccountId;"); + auto local_user_id = EOS4J::javaLongFromObjectField(env, local_user_id_obj, "ptr"); + jboolean include_redeemed = EOS4J::javaBooleanFromObjectField(env, options, "includeRedeemed"); + + std::vector entitlement_names = EOS4J::javaStringVectorFromObjectField(env, options, "entitlementNames"); + const char* entitlements[entitlement_names.size()]; + for (size_t i = 0; i < entitlement_names.size(); i++) { + entitlements[i] = entitlement_names.at(i).c_str(); + } + + EOS_Ecom_QueryEntitlementsOptions query_options; + memset(&query_options, 0, sizeof(query_options)); + query_options.ApiVersion = EOS_ECOM_QUERYENTITLEMENTS_API_LATEST; + query_options.LocalUserId = reinterpret_cast(local_user_id); + query_options.EntitlementNames = reinterpret_cast(entitlements); + query_options.EntitlementNameCount = entitlement_names.size(); + query_options.bIncludeRedeemed = static_cast(include_redeemed); + + auto callback_adapter = std::make_unique(env, callback); + EOS_Ecom_QueryEntitlements(reinterpret_cast(handle), &query_options, callback_adapter.release(), [](const EOS_Ecom_QueryEntitlementsCallbackInfo* data) -> void { + std::unique_ptr callback_adapter{reinterpret_cast(data->ClientData)}; + callback_adapter->attach([&](JNIEnv* env, jobject callback) -> void { + jclass eaid_cls = env->FindClass("com/bearwaves/eos4j/EOS$EpicAccountId"); + jmethodID eaid_ctor = env->GetMethodID(eaid_cls, "", "(J)V"); + auto local_user_id = env->NewObject(eaid_cls, eaid_ctor, data->LocalUserId); + + jclass callback_info_class = env->FindClass("com/bearwaves/eos4j/EOSEcom$QueryEntitlementsCallbackInfo"); + jmethodID callback_info_ctor = env->GetMethodID(callback_info_class, "", "(ILcom/bearwaves/eos4j/EOS$EpicAccountId;)V"); + auto callback_info = env->NewObject(callback_info_class, callback_info_ctor, static_cast(data->ResultCode), local_user_id); + + jclass cls = env->GetObjectClass(callback); + jmethodID mid = env->GetMethodID(cls, "run", "(Lcom/bearwaves/eos4j/EOSEcom$QueryEntitlementsCallbackInfo;)V"); + env->CallVoidMethod(callback, mid, callback_info); + }); + }); + */ + + static native int getEntitlementsCount(long handle, EOSEcom.GetEntitlementsCountOptions options); /* + jobject local_user_id_obj = EOS4J::javaObjectFromObjectField(env, options, "localUserId", "Lcom/bearwaves/eos4j/EOS$EpicAccountId;"); + auto local_user_id = EOS4J::javaLongFromObjectField(env, local_user_id_obj, "ptr"); + + EOS_Ecom_GetEntitlementsCountOptions count_options; + memset(&count_options, 0, sizeof(count_options)); + count_options.ApiVersion = EOS_ECOM_GETENTITLEMENTSCOUNT_API_LATEST; + count_options.LocalUserId = reinterpret_cast(local_user_id); + + return EOS_Ecom_GetEntitlementsCount(reinterpret_cast(handle), &count_options); + */ + + static native int getEntitlementsByNameCount(long handle, EOSEcom.GetEntitlementsByNameCountOptions options); /* + jobject local_user_id_obj = EOS4J::javaObjectFromObjectField(env, options, "localUserId", "Lcom/bearwaves/eos4j/EOS$EpicAccountId;"); + auto local_user_id = EOS4J::javaLongFromObjectField(env, local_user_id_obj, "ptr"); + auto name = EOS4J::javaStringFromObjectField(env, options, "entitlementName"); + + EOS_Ecom_GetEntitlementsByNameCountOptions count_options; + memset(&count_options, 0, sizeof(count_options)); + count_options.ApiVersion = EOS_ECOM_GETENTITLEMENTSBYNAMECOUNT_API_LATEST; + count_options.LocalUserId = reinterpret_cast(local_user_id); + count_options.EntitlementName = name->c_str(); + + return EOS_Ecom_GetEntitlementsByNameCount(reinterpret_cast(handle), &count_options); + */ + + static native EOSEcom.Entitlement copyEntitlementByIndex( + long handle, EOSEcom.CopyEntitlementByIndexOptions options + ) throws EOSException; /* + jobject local_user_id_obj = EOS4J::javaObjectFromObjectField(env, options, "localUserId", "Lcom/bearwaves/eos4j/EOS$EpicAccountId;"); + auto local_user_id = EOS4J::javaLongFromObjectField(env, local_user_id_obj, "ptr"); + auto index = EOS4J::javaIntFromObjectField(env, options, "entitlementIndex"); + + EOS_Ecom_CopyEntitlementByIndexOptions copy_options; + memset(©_options, 0, sizeof(copy_options)); + copy_options.ApiVersion = EOS_ECOM_COPYENTITLEMENTBYINDEX_API_LATEST; + copy_options.LocalUserId = reinterpret_cast(local_user_id); + copy_options.EntitlementIndex = static_cast(index); + + EOS_Ecom_Entitlement* out; + auto copy_result = EOS_Ecom_CopyEntitlementByIndex(reinterpret_cast(handle), ©_options, &out); + if (copy_result != EOS_EResult::EOS_Success) { + EOS4J::throwEOSException(env, static_cast(copy_result)); + return nullptr; + } + + jclass result_cls = env->FindClass("com/bearwaves/eos4j/EOSEcom$Entitlement"); + jmethodID result_ctor = env->GetMethodID(result_cls, "", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;IZLjava/util/Date;)V"); + + jclass date_cls = env->FindClass("java/util/Date"); + jmethodID date_ctor = env->GetMethodID(date_cls, "", "(J)V"); + jobject end = out->EndTimestamp == EOS_ECOM_ENTITLEMENT_ENDTIMESTAMP_UNDEFINED ? nullptr : env->NewObject(date_cls, date_ctor, out->EndTimestamp); + + return env->NewObject( + result_cls, + result_ctor, + (long long) out, + env->NewStringUTF(out->EntitlementName), + env->NewStringUTF(out->EntitlementId), + env->NewStringUTF(out->CatalogItemId), + out->ServerIndex, + out->bRedeemed, + end + ); + */ + + static native EOSEcom.Entitlement copyEntitlementById( + long handle, EOSEcom.CopyEntitlementByIdOptions options + ) throws EOSException; /* + jobject local_user_id_obj = EOS4J::javaObjectFromObjectField(env, options, "localUserId", "Lcom/bearwaves/eos4j/EOS$EpicAccountId;"); + auto local_user_id = EOS4J::javaLongFromObjectField(env, local_user_id_obj, "ptr"); + auto id = EOS4J::javaStringFromObjectField(env, options, "entitlementId"); + + EOS_Ecom_CopyEntitlementByIdOptions copy_options; + memset(©_options, 0, sizeof(copy_options)); + copy_options.ApiVersion = EOS_ECOM_COPYENTITLEMENTBYID_API_LATEST; + copy_options.LocalUserId = reinterpret_cast(local_user_id); + copy_options.EntitlementId = id->c_str(); + + EOS_Ecom_Entitlement* out; + auto copy_result = EOS_Ecom_CopyEntitlementById(reinterpret_cast(handle), ©_options, &out); + if (copy_result != EOS_EResult::EOS_Success) { + EOS4J::throwEOSException(env, static_cast(copy_result)); + return nullptr; + } + + jclass result_cls = env->FindClass("com/bearwaves/eos4j/EOSEcom$Entitlement"); + jmethodID result_ctor = env->GetMethodID(result_cls, "", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;IZLjava/util/Date;)V"); + + jclass date_cls = env->FindClass("java/util/Date"); + jmethodID date_ctor = env->GetMethodID(date_cls, "", "(J)V"); + jobject end = out->EndTimestamp == EOS_ECOM_ENTITLEMENT_ENDTIMESTAMP_UNDEFINED ? nullptr : env->NewObject(date_cls, date_ctor, out->EndTimestamp); + + return env->NewObject( + result_cls, + result_ctor, + (long long) out, + env->NewStringUTF(out->EntitlementName), + env->NewStringUTF(out->EntitlementId), + env->NewStringUTF(out->CatalogItemId), + out->ServerIndex, + out->bRedeemed, + end + ); + */ + + static native EOSEcom.Entitlement copyEntitlementByNameAndIndex( + long handle, EOSEcom.CopyEntitlementByNameAndIndexOptions options + ) throws EOSException; /* + jobject local_user_id_obj = EOS4J::javaObjectFromObjectField(env, options, "localUserId", "Lcom/bearwaves/eos4j/EOS$EpicAccountId;"); + auto local_user_id = EOS4J::javaLongFromObjectField(env, local_user_id_obj, "ptr"); + auto name = EOS4J::javaStringFromObjectField(env, options, "entitlementName"); + auto index = EOS4J::javaIntFromObjectField(env, options, "index"); + + EOS_Ecom_CopyEntitlementByNameAndIndexOptions copy_options; + memset(©_options, 0, sizeof(copy_options)); + copy_options.ApiVersion = EOS_ECOM_COPYENTITLEMENTBYNAMEANDINDEX_API_LATEST; + copy_options.LocalUserId = reinterpret_cast(local_user_id); + copy_options.EntitlementName = name->c_str(); + copy_options.Index = static_cast(index); + + EOS_Ecom_Entitlement* out; + auto copy_result = EOS_Ecom_CopyEntitlementByNameAndIndex(reinterpret_cast(handle), ©_options, &out); + if (copy_result != EOS_EResult::EOS_Success) { + EOS4J::throwEOSException(env, static_cast(copy_result)); + return nullptr; + } + + jclass result_cls = env->FindClass("com/bearwaves/eos4j/EOSEcom$Entitlement"); + jmethodID result_ctor = env->GetMethodID(result_cls, "", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;IZLjava/util/Date;)V"); + + jclass date_cls = env->FindClass("java/util/Date"); + jmethodID date_ctor = env->GetMethodID(date_cls, "", "(J)V"); + jobject end = out->EndTimestamp == EOS_ECOM_ENTITLEMENT_ENDTIMESTAMP_UNDEFINED ? nullptr : env->NewObject(date_cls, date_ctor, out->EndTimestamp); + + return env->NewObject( + result_cls, + result_ctor, + (long long) out, + env->NewStringUTF(out->EntitlementName), + env->NewStringUTF(out->EntitlementId), + env->NewStringUTF(out->CatalogItemId), + out->ServerIndex, + out->bRedeemed, + end + ); + */ + + static native void releaseEntitlement(long handle); /* + EOS_Ecom_Entitlement_Release(reinterpret_cast(handle)); + */ }