rdiscord_sdk 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +13 -0
  3. data/.vscode/c_cpp_properties.json +24 -0
  4. data/.vscode/settings.json +102 -0
  5. data/Gemfile +11 -0
  6. data/Gemfile.lock +46 -0
  7. data/INTERNALS.md +0 -0
  8. data/LICENSE +674 -0
  9. data/README.md +187 -0
  10. data/Rakefile +17 -0
  11. data/bin/console +15 -0
  12. data/bin/setup +8 -0
  13. data/ext/rdiscord_sdk/activity.cpp +297 -0
  14. data/ext/rdiscord_sdk/activity.h +17 -0
  15. data/ext/rdiscord_sdk/common.cpp +65 -0
  16. data/ext/rdiscord_sdk/common.h +88 -0
  17. data/ext/rdiscord_sdk/extconf.rb +54 -0
  18. data/ext/rdiscord_sdk/gem_activity_manager.cpp +273 -0
  19. data/ext/rdiscord_sdk/gem_activity_manager.h +8 -0
  20. data/ext/rdiscord_sdk/gem_user_manager.cpp +114 -0
  21. data/ext/rdiscord_sdk/gem_user_manager.h +8 -0
  22. data/ext/rdiscord_sdk/rdiscord_sdk.cpp +77 -0
  23. data/ext/rdiscord_sdk/rdiscord_sdk.h +17 -0
  24. data/ext/rdiscord_sdk/user.cpp +98 -0
  25. data/ext/rdiscord_sdk/user.h +19 -0
  26. data/lib/rdiscord_sdk/enums.rb +162 -0
  27. data/lib/rdiscord_sdk/rdiscord_sdk.so +0 -0
  28. data/lib/rdiscord_sdk/version.rb +16 -0
  29. data/lib/rdiscord_sdk.rb +3 -0
  30. data/rdiscord_sdk.gemspec +34 -0
  31. data/third-party/include/achievement_manager.cpp +98 -0
  32. data/third-party/include/achievement_manager.h +34 -0
  33. data/third-party/include/activity_manager.cpp +177 -0
  34. data/third-party/include/activity_manager.h +42 -0
  35. data/third-party/include/application_manager.cpp +78 -0
  36. data/third-party/include/application_manager.h +30 -0
  37. data/third-party/include/core.cpp +182 -0
  38. data/third-party/include/core.h +64 -0
  39. data/third-party/include/discord.h +16 -0
  40. data/third-party/include/event.h +59 -0
  41. data/third-party/include/ffi.h +942 -0
  42. data/third-party/include/image_manager.cpp +57 -0
  43. data/third-party/include/image_manager.h +28 -0
  44. data/third-party/include/lobby_manager.cpp +547 -0
  45. data/third-party/include/lobby_manager.h +88 -0
  46. data/third-party/include/network_manager.cpp +103 -0
  47. data/third-party/include/network_manager.h +63 -0
  48. data/third-party/include/overlay_manager.cpp +112 -0
  49. data/third-party/include/overlay_manager.h +33 -0
  50. data/third-party/include/relationship_manager.cpp +90 -0
  51. data/third-party/include/relationship_manager.h +32 -0
  52. data/third-party/include/storage_manager.cpp +158 -0
  53. data/third-party/include/storage_manager.h +46 -0
  54. data/third-party/include/store_manager.cpp +160 -0
  55. data/third-party/include/store_manager.h +38 -0
  56. data/third-party/include/types.cpp +769 -0
  57. data/third-party/include/types.h +492 -0
  58. data/third-party/include/user_manager.cpp +80 -0
  59. data/third-party/include/user_manager.h +31 -0
  60. data/third-party/include/voice_manager.cpp +124 -0
  61. data/third-party/include/voice_manager.h +37 -0
  62. data/third-party/lib/x86/discord_game_sdk.dll +0 -0
  63. data/third-party/lib/x86/discord_game_sdk.dll.lib +0 -0
  64. data/third-party/lib/x86_64/discord_game_sdk.bundle +0 -0
  65. data/third-party/lib/x86_64/discord_game_sdk.dll +0 -0
  66. data/third-party/lib/x86_64/discord_game_sdk.dll.lib +0 -0
  67. data/third-party/lib/x86_64/discord_game_sdk.dylib +0 -0
  68. data/third-party/lib/x86_64/discord_game_sdk.so +0 -0
  69. metadata +114 -0
data/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # R(uby) Discord SDK
2
+
3
+ This is a Ruby gem that implements bindings to the [Discord Game SDK](https://discord.com/developers/docs/game-sdk/discord).
4
+ It is intended to be used in [ModShot](https://github.com/Astrabit-ST/Modshot-Core), although will work in any ruby application.
5
+
6
+ ## Whats the difference between this and ruby_discord_game_sdk?
7
+
8
+ Well, [ruby_discord_game_sdk](https://github.com/rkevin-arch/ruby_discord_game_sdk) is written in pure C, making it very hard to understand and interpret.
9
+ This means it's very difficult to understand how it works, what it does, and to add new features.
10
+ rdiscord_sdk is instead built in C++ meaning it's easier to abstract, and to modify the source. The name may be obtuse, but it sure as hell isn't internally.
11
+ My goal is to provide extra levels of abstraction over ruby_discord_game_sdk, and provide full functionality as well. Wether that will happen, I'm not sure.
12
+
13
+ ## Disclaimer
14
+ Some portions of code are untested because they can be extremely hard to test, namely events.
15
+ Keep that in mind.
16
+
17
+ ## Usage
18
+
19
+ This gem (at the moment) exposes SDK functions without much abstraction, so as long as you can grasp C#, you should be able to transfer the example code to ruby code.
20
+ There are a couple of minor differences, such as the lack of a need to initialize managers (C++ Discord SDK bindings automatically do that for you).
21
+
22
+ - Setting up the SDK is the same as ruby_discord_game_sdk `Discord::init(client_id, flags)`
23
+ - Enums are just constants inside lib/rdiscord_sdk/enums.rb (So `Discord.Result.Ok` ~> `Discord::Result::Ok`)
24
+ - The module for SDK functions is under `Discord`, not `DiscordSDK`
25
+ - Callbacks are method blocks
26
+ - Events are also method blocks
27
+ - Pending callbacks and events are accessible
28
+ - Some functions return an array, usually the result being at [0] and an object at [1] (such as Discord::UserManager.get_current_user)
29
+
30
+ As mentioned above, some functions return arrays. An easy way to deal with these would be to:
31
+ ```rb
32
+ result, user = Discord::UserManager.get_current_user
33
+ ```
34
+ It's not the best, but it works. I don't want to discard a result, in case you ever want to know what went wrong.
35
+ If you don't want the result, you can just do:
36
+ ```rb
37
+ _, user = Discord::UserManager.get_current_user
38
+ ```
39
+ `_` is widely understood as a dummy variable, so it's good practice to use it when you don't care about a specific return value.
40
+
41
+ ## Callbacks & Events
42
+
43
+ As mentioned before, callbacks and events are method blocks and procs, and are not usually required. If you've coded ruby before, just use them how you normally would.
44
+ Generally, when you see `() => {}` in the SDK documentation, that is referring to a callback or event, and so you should substitute it with a block instead.
45
+
46
+ Docs:
47
+ ```cs
48
+ var userManager = discord.GetUserManager();
49
+ var activity = new Discord.Activity
50
+ activityManager.UpdateActivity(activity, (result) =>
51
+ {
52
+ if (result == Discord.Result.Ok)
53
+ {
54
+ Console.WriteLine("Success!");
55
+ }
56
+ else
57
+ {
58
+ Console.WriteLine("Failed");
59
+ }
60
+ }
61
+ ```
62
+ rdiscord_sdk equivalent:
63
+ ```rb
64
+ Discord::ActivityManager.update_activity(Discord::Activity.new) do |result|
65
+ if result == Discord::Result::Ok
66
+ puts "Success!"
67
+ else
68
+ puts "Failed"
69
+ end
70
+ end
71
+ ```
72
+
73
+ If no block is provided, and an error occurs, it should be logged to stderr. (or your log hook if that is set up)
74
+
75
+ Events work a little bit differently than in the SDK docs. As far as I can tell, the docs don't cover "connecting" or "disconnecting".
76
+ Events require you to "connect" to them, meaning you can subscribe multiple blocks to any single event. (iirc the cap is 4?)
77
+ When you add something to an event, it will return a token, an identifier to the block passed into the event, which **must** be used when removing blocks from an event.
78
+ It's sort of like a subscriber system, where things can subscribe to an event, and then unsubscribe from said event at any point.
79
+
80
+ Events and pending callbacks are stored in a global array and hash respectively, if you ever need to access them for some reason.
81
+ **I would not suggest trying to modify them.** It will inevitably cause bad problems.
82
+
83
+ C# code:
84
+ ```cs
85
+ activityManager.OnActivityJoin += secret => {
86
+ Console.WriteLine("OnJoin {0}", secret);
87
+ }
88
+ ```
89
+ rdiscord_sdk equivalent:
90
+ ```rb
91
+ token = Discord::ActivityManager.on_activity_join_connect do |secret|
92
+ puts "OnJoin #{secret}"
93
+ end
94
+
95
+ Discord::ActivtyManager.on_activity_join_disconnect(token) # I'm not sure what the C# equivalent is
96
+ ```
97
+
98
+ ## Installation
99
+
100
+ Add this line to your application's Gemfile:
101
+
102
+ ```ruby
103
+ gem 'rdiscord_sdk'
104
+ ```
105
+
106
+ And then execute:
107
+
108
+ $ bundle install
109
+
110
+ Or install it yourself as:
111
+
112
+ $ gem install rdiscord_sdk
113
+
114
+
115
+ ## Development
116
+
117
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
118
+
119
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
120
+
121
+ ## License
122
+
123
+ The gem is available as open source under the terms of the [GPL-3]() license.
124
+
125
+ This gem also uses the [Discord SDK](https://discord.com/developers/docs/game-sdk/discord), which is proprietary. Everything under `third_party/` is owned by Discord.
126
+
127
+ ## Contributing
128
+
129
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Speak2Erase/rdiscord_sdk.
130
+
131
+ ## Development Progress
132
+
133
+ ### Data Classes
134
+
135
+ - [x] DiscordUser
136
+ - [ ] DiscordOAuth2Token
137
+ - [ ] DiscordImageHandle
138
+ - [ ] DiscordImageDimensions
139
+ - [x] DiscordActivityTimestamps
140
+ - [x] DiscordActivityAssets
141
+ - [x] DiscordPartySize
142
+ - [x] DiscordActivityParty
143
+ - [x] DiscordActivitySecrets
144
+ - [x] DiscordActivity
145
+ - [ ] DiscordPresence
146
+ - [ ] DiscordRelationship
147
+ - [ ] DiscordLobby
148
+ - [ ] DiscordFileStat
149
+ - [ ] DiscordEntitlement
150
+ - [ ] DiscordSkuPrive
151
+ - [ ] DiscordSku
152
+ - [ ] DiscordInputMode
153
+ - [ ] DiscordUserAchievement
154
+
155
+ ### Managers implemented
156
+ - [ ] ApplicationManager
157
+ - [x] UserManager
158
+ - [ ] ImageManager
159
+ - [x] ActivityManager
160
+ - [ ] RelationshipManager
161
+ - [ ] LobbyManager
162
+ - [ ] NetworkManager
163
+ - [ ] OverlayManager
164
+ - [ ] StorageManager
165
+ - [ ] StoreManager
166
+ - [ ] VoiceManager
167
+ - [ ] AchievementManager
168
+
169
+ ### Others
170
+ - [ ] Core functionality
171
+ - [x] Initialization
172
+ - [ ] Teardown
173
+ - [x] Run callbacks
174
+ - [x] Log hooks
175
+ - [x] All enums
176
+ - [ ] DiscordLobbyTransaction
177
+ - [ ] DiscordLobbySearchQuery
178
+ - [x] Events
179
+ - [x] UserEvents
180
+ - [x] ActivityEvents
181
+ - [ ] RelationshipEvents
182
+ - [ ] LobbyEvents
183
+ - [ ] NetworkEvents
184
+ - [ ] OverlayEvents
185
+ - [ ] StoreEvents
186
+ - [ ] VoiceEvents
187
+ - [ ] AchievementEvents
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rubocop/rake_task"
5
+ require "rake/extensiontask"
6
+
7
+ RuboCop::RakeTask.new
8
+
9
+ task default: :rubocop
10
+
11
+ task build: :compile
12
+
13
+ Rake::ExtensionTask.new("rdiscord_sdk") do |ext|
14
+ ext.lib_dir = "lib/rdiscord_sdk"
15
+ end
16
+
17
+ task default: %i[clobber compile]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "rdiscord_sdk"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,297 @@
1
+ #include "activity.h"
2
+ #include <rice/rice.hpp>
3
+ #include "discord.h"
4
+ #include "common.h"
5
+ #include <cstdint>
6
+ using namespace Rice;
7
+
8
+ Class rb_cActivity;
9
+
10
+ DEF_TYPE_CUSTOMTYPENAME(discord::Activity, Activity_rbType);
11
+
12
+ Object rb_activity_initialize(Object self) {
13
+ discord::Activity* activity = new discord::Activity();
14
+ setPrivateData(self, activity);
15
+
16
+ return self;
17
+ }
18
+
19
+ int rb_activity_get_type(Object self) {
20
+ GET_ACTIVITY(self);
21
+
22
+ return (int) activity->GetType();
23
+ }
24
+
25
+ Object rb_activity_set_type(Object self, int type) {
26
+ GET_ACTIVITY(self);
27
+
28
+ activity->SetType((discord::ActivityType) type);
29
+
30
+ return Qnil;
31
+ }
32
+
33
+ std::int64_t rb_activity_get_application_id(Object self) {
34
+ GET_ACTIVITY(self);
35
+
36
+ return activity->GetApplicationId();
37
+ }
38
+
39
+ Object rb_activity_set_application_id(Object self, std::int64_t id) {
40
+ GET_ACTIVITY(self);
41
+
42
+ activity->SetApplicationId(id);
43
+
44
+ return Qnil;
45
+ }
46
+
47
+ const char* rb_activity_get_name(Object self) {
48
+ GET_ACTIVITY(self);
49
+
50
+ return activity->GetName();
51
+ }
52
+
53
+ Object rb_activity_set_name(Object self, const char* name) {
54
+ GET_ACTIVITY(self);
55
+
56
+ activity->SetName(name);
57
+
58
+ return Qnil;
59
+ }
60
+
61
+ const char* rb_activity_get_state(Object self) {
62
+ GET_ACTIVITY(self);
63
+
64
+ return activity->GetState();
65
+ }
66
+
67
+ Object rb_activity_set_state(Object self, const char* state) {
68
+ GET_ACTIVITY(self);
69
+
70
+ activity->SetState(state);
71
+
72
+ return Qnil;
73
+ }
74
+
75
+ const char* rb_activity_get_details(Object self) {
76
+ GET_ACTIVITY(self);
77
+
78
+ return activity->GetDetails();
79
+ }
80
+
81
+ Object rb_activity_set_details(Object self, const char* details) {
82
+ GET_ACTIVITY(self);
83
+
84
+ activity->SetDetails(details);
85
+
86
+ return Qnil;
87
+ }
88
+
89
+ bool rb_activity_get_instance(Object self) {
90
+ GET_ACTIVITY(self);
91
+
92
+ return activity->GetInstance();
93
+ }
94
+
95
+ Object rb_activity_set_instance(Object self, bool instance) {
96
+ GET_ACTIVITY(self);
97
+
98
+ activity->SetInstance(instance);
99
+
100
+ return Qnil;
101
+ }
102
+
103
+ std::int64_t rb_activity_timestamp_get_timestamp_start(Object self) {
104
+ GET_ACTIVITY(self);
105
+
106
+ return activity->GetTimestamps().GetStart();
107
+ }
108
+
109
+ Object rb_activity_timestamp_set_timestamp_start(Object self, std::int64_t start) {
110
+ GET_ACTIVITY(self);
111
+
112
+ activity->GetTimestamps().SetStart(start);
113
+
114
+ return Qnil;
115
+ }
116
+
117
+ std::int64_t rb_activity_timestamp_get_timestamp_end(Object self) {
118
+ GET_ACTIVITY(self);
119
+
120
+ return activity->GetTimestamps().GetEnd();
121
+ }
122
+
123
+ Object rb_activity_timestamp_set_timestamp_end(Object self, std::int64_t end) {
124
+ GET_ACTIVITY(self);
125
+
126
+ activity->GetTimestamps().SetEnd(end);
127
+
128
+ return Qnil;
129
+ }
130
+
131
+ const char* rb_activity_assets_get_large_image(Object self) {
132
+ GET_ACTIVITY(self);
133
+
134
+ return activity->GetAssets().GetLargeImage();
135
+ }
136
+
137
+ Object rb_activity_assets_set_large_image(Object self, const char* largeImage) {
138
+ GET_ACTIVITY(self);
139
+
140
+ activity->GetAssets().SetLargeImage(largeImage);
141
+
142
+ return Qnil;
143
+ }
144
+
145
+ const char* rb_activity_assets_get_large_text(Object self) {
146
+ GET_ACTIVITY(self);
147
+
148
+ return activity->GetAssets().GetLargeText();
149
+ }
150
+
151
+ Object rb_activity_assets_set_large_text(Object self, const char* largeText) {
152
+ GET_ACTIVITY(self);
153
+
154
+ activity->GetAssets().SetLargeText(largeText);
155
+
156
+ return Qnil;
157
+ }
158
+
159
+ const char* rb_activity_assets_get_small_image(Object self) {
160
+ GET_ACTIVITY(self);
161
+
162
+ return activity->GetAssets().GetSmallImage();
163
+ }
164
+
165
+ Object rb_activity_assets_set_small_image(Object self, const char* smallImage) {
166
+ GET_ACTIVITY(self);
167
+
168
+ activity->GetAssets().SetSmallImage(smallImage);
169
+
170
+ return Qnil;
171
+ }
172
+
173
+ const char* rb_activity_assets_get_small_text(Object self) {
174
+ GET_ACTIVITY(self);
175
+
176
+ return activity->GetAssets().GetSmallText();
177
+ }
178
+
179
+ Object rb_activity_assets_set_small_text(Object self, const char* smallText) {
180
+ GET_ACTIVITY(self);
181
+
182
+ activity->GetAssets().SetSmallText(smallText);
183
+
184
+ return Qnil;
185
+ }
186
+
187
+ const char* rb_activity_party_get_party_id(Object self) {
188
+ GET_ACTIVITY(self);
189
+
190
+ return activity->GetParty().GetId();
191
+ }
192
+
193
+ Object rb_activity_party_set_party_id(Object self, const char* id) {
194
+ GET_ACTIVITY(self);
195
+
196
+ activity->GetParty().SetId(id);
197
+
198
+ return Qnil;
199
+ }
200
+
201
+ std::int32_t rb_activity_party_get_party_size(Object self) {
202
+ GET_ACTIVITY(self);
203
+
204
+ return activity->GetParty().GetSize().GetCurrentSize();
205
+ }
206
+
207
+ Object rb_activity_party_set_party_size(Object self, std::int32_t size) {
208
+ GET_ACTIVITY(self);
209
+
210
+ activity->GetParty().GetSize().SetCurrentSize(size);
211
+
212
+ return Qnil;
213
+ }
214
+
215
+ std::int32_t rb_activity_party_get_party_max(Object self) {
216
+ GET_ACTIVITY(self);
217
+
218
+ return activity->GetParty().GetSize().GetMaxSize();
219
+ }
220
+
221
+ Object rb_activity_party_set_party_max(Object self, std::int32_t max) {
222
+ GET_ACTIVITY(self);
223
+
224
+ activity->GetParty().GetSize().SetMaxSize(max);
225
+
226
+ return Qnil;
227
+ }
228
+
229
+ const char* rb_activity_secrets_get_secret_match(Object self) {
230
+ GET_ACTIVITY(self);
231
+
232
+ return activity->GetSecrets().GetMatch();
233
+ }
234
+
235
+ Object rb_activity_secrets_set_secret_match(Object self, const char* match) {
236
+ GET_ACTIVITY(self);
237
+
238
+ activity->GetSecrets().SetMatch(match);
239
+
240
+ return Qnil;
241
+ }
242
+
243
+ const char* rb_activity_secrets_get_secret_join(Object self) {
244
+ GET_ACTIVITY(self);
245
+
246
+ return activity->GetSecrets().GetJoin();
247
+ }
248
+
249
+ Object rb_activity_secrets_set_secret_join(Object self, const char* join) {
250
+ GET_ACTIVITY(self);
251
+
252
+ activity->GetSecrets().SetJoin(join);
253
+
254
+ return Qnil;
255
+ }
256
+
257
+ const char* rb_activity_secrets_get_secret_spectate(Object self) {
258
+ GET_ACTIVITY(self);
259
+
260
+ return activity->GetSecrets().GetSpectate();
261
+ }
262
+
263
+ Object rb_activity_secrets_set_secret_spectate(Object self, const char* spectate) {
264
+ GET_ACTIVITY(self);
265
+
266
+ activity->GetSecrets().SetSpectate(spectate);
267
+
268
+ return Qnil;
269
+ }
270
+
271
+ void rb_activity_init_class(Module module) {
272
+ rb_cActivity = define_class_under(module, "Activity");
273
+ rb_cActivity.define_method("initialize", &rb_activity_initialize);
274
+ rb_define_alloc_func(rb_cActivity, classAllocate<&Activity_rbType>);
275
+ DEF_METHOD_GET_SET(rb_cActivity, type, activity);
276
+ DEF_METHOD_GET_SET(rb_cActivity, application_id, activity);
277
+ DEF_METHOD_GET_SET(rb_cActivity, name, activity);
278
+ DEF_METHOD_GET_SET(rb_cActivity, state, activity);
279
+ DEF_METHOD_GET_SET(rb_cActivity, details, activity);
280
+ DEF_METHOD_GET_SET(rb_cActivity, instance, activity);
281
+ // Timestamps
282
+ DEF_METHOD_GET_SET(rb_cActivity, timestamp_start, activity_timestamp);
283
+ DEF_METHOD_GET_SET(rb_cActivity, timestamp_end, activity_timestamp);
284
+ // Assets
285
+ DEF_METHOD_GET_SET(rb_cActivity, large_image, activity_assets);
286
+ DEF_METHOD_GET_SET(rb_cActivity, large_text, activity_assets);
287
+ DEF_METHOD_GET_SET(rb_cActivity, small_image, activity_assets);
288
+ DEF_METHOD_GET_SET(rb_cActivity, small_text, activity_assets);
289
+ // Party
290
+ DEF_METHOD_GET_SET(rb_cActivity, party_id, activity_party);
291
+ DEF_METHOD_GET_SET(rb_cActivity, party_size, activity_party);
292
+ DEF_METHOD_GET_SET(rb_cActivity, party_max, activity_party);
293
+ // Secrets
294
+ DEF_METHOD_GET_SET(rb_cActivity, secret_match, activity_secrets);
295
+ DEF_METHOD_GET_SET(rb_cActivity, secret_join, activity_secrets);
296
+ DEF_METHOD_GET_SET(rb_cActivity, secret_spectate, activity_secrets);
297
+ }
@@ -0,0 +1,17 @@
1
+ #pragma once
2
+
3
+ #include <rice/rice.hpp>
4
+ #include "rdiscord_sdk.h"
5
+ #include "discord.h"
6
+ #include "common.h"
7
+
8
+ using namespace Rice;
9
+
10
+ extern Class rb_cActivity;
11
+ void rb_activity_init_class(Module module);
12
+
13
+ #define GET_ACTIVITY(obj) \
14
+ if (!obj.is_a(rb_cActivity)) { \
15
+ rb_raise(rb_eTypeError, "Activity is not a Discord::Activity"); \
16
+ } \
17
+ discord::Activity* activity = getPrivateData<discord::Activity>(obj);
@@ -0,0 +1,65 @@
1
+ #include "common.h"
2
+ #include <functional>
3
+ #include <iostream>
4
+
5
+ using namespace Rice;
6
+
7
+ VALUE rb_common_get_callback_proc(int args) {
8
+ if (!rb_block_given_p())
9
+ {
10
+ return Qnil;
11
+ }
12
+ VALUE proc = rb_block_proc();
13
+ if (rb_proc_arity(proc) != args) {
14
+ rb_raise(rb_eRuntimeError, "Passed block should take %d arguments, got %d instead", args, rb_proc_arity(proc));
15
+ }
16
+ rb_ary_push(rb_oPendingCallbacks, proc);
17
+ return proc;
18
+ }
19
+
20
+ VALUE rb_common_get_event_proc(int args) {
21
+ if (!rb_block_given_p())
22
+ {
23
+ return Qnil;
24
+ }
25
+
26
+ VALUE proc = rb_block_proc();
27
+ if (rb_proc_arity(proc) != args) {
28
+ rb_raise(rb_eRuntimeError, "Passed block should take %d arguments, got %d instead", args, rb_proc_arity(proc));
29
+ }
30
+ return proc;
31
+ }
32
+
33
+ void rb_common_add_proc_to_hash(VALUE key, VALUE proc) {
34
+ rb_hash_aset(rb_oProcEvents, key, proc);
35
+ }
36
+
37
+ VALUE rb_result_to_obj(discord::Result result) {
38
+ return INT2NUM((int) result);
39
+ }
40
+
41
+ VALUE rb_discord_call_proc(VALUE ary) {
42
+ VALUE proc = rb_ary_shift(ary);
43
+ return rb_proc_call(proc, ary);
44
+ }
45
+
46
+ /* Discord's C++ API doesn't have callback data, so this is the easiest way (i could think of) to make a callback know what proc it has */
47
+ std::function<void(discord::Result)> rb_discord_callback_wrapper_basic(VALUE proc) {
48
+ std::function<void(discord::Result)> fn = [proc](discord::Result result){
49
+ if (proc == Qnil)
50
+ return;
51
+
52
+ if (!rb_obj_is_kind_of(proc, rb_cProc)) {
53
+ rb_raise(rb_eTypeError, "Proc expected in callback, got %d instead", rb_obj_classname(proc));
54
+ }
55
+
56
+ rb_ary_delete(rb_oPendingCallbacks, proc);
57
+ VALUE ary = rb_ary_new_from_args(2, proc, INT2NUM((int) result));
58
+
59
+ int state;
60
+ rb_protect(rb_discord_call_proc, ary, &state);
61
+ LOG_ERROR_IF_STATE;
62
+ };
63
+ return fn;
64
+ }
65
+
@@ -0,0 +1,88 @@
1
+ #pragma once
2
+
3
+ #include "rdiscord_sdk.h"
4
+ #include <exception>
5
+
6
+ #define BOOL2RB(val) ((val) ? Qtrue : Qfalse)
7
+
8
+ #define CHECK_CORE_INITIALIZED \
9
+ if (!DiscordSDK.core) \
10
+ rb_raise(rb_eRuntimeError, "The Discord SDK core is not initialized!");
11
+
12
+ template <class C> inline C *getPrivateData(VALUE self) {
13
+ C *c = static_cast<C *>(RTYPEDDATA_DATA(self));
14
+ if (!c) {
15
+ rb_raise(rb_eStandardError, "RTYPEDDATA_DATA for object missing data");
16
+ }
17
+ return c;
18
+ }
19
+
20
+ static inline void setPrivateData(VALUE self, void *p) {
21
+ RTYPEDDATA_DATA(self) = p;
22
+ }
23
+
24
+
25
+ #define GUARD_EXC(exp) \
26
+ { \
27
+ try { \
28
+ exp \
29
+ } catch (std::exception &error) { \
30
+ rb_raise(rb_eFatal, "%s", error.what();) \
31
+ } \
32
+ }
33
+
34
+ template <rb_data_type_t *rbType> static VALUE classAllocate(VALUE klass) {
35
+ return rb_data_typed_object_wrap(klass, 0, rbType);
36
+ }
37
+
38
+ template <class C> static void freeInstance(void *inst) {
39
+ delete static_cast<C *>(inst);
40
+ }
41
+
42
+ #define DEF_TYPE_FLAGS 0
43
+
44
+ #define DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, Name, Free, Typename) \
45
+ rb_data_type_t Typename = {Name, {0, Free, 0, 0, 0}, 0, 0, DEF_TYPE_FLAGS}
46
+
47
+ #define DEF_TYPE_CUSTOMTYPENAME(Klass, Typename) \
48
+ DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, #Klass, freeInstance<Klass>, Typename)
49
+
50
+ #define DEF_TYPE_CUSTOMNAME(Klass, Name) \
51
+ DEF_TYPE_CUSTOMNAME_AND_FREE(Klass, Name, freeInstance<Klass>, Klass##_rbType)
52
+
53
+ #define DEF_TYPE(Klass) DEF_TYPE_CUSTOMNAME(Klass, #Klass)
54
+
55
+ using namespace Rice;
56
+
57
+ #define DEF_METHOD_SET(klass, name, subclass) \
58
+ klass.define_method(#name, &rb_##subclass##_get_##name);
59
+
60
+ #define DEF_METHOD_GET(klass, name, subclass) \
61
+ klass.define_method(#name "=", &rb_##subclass##_set_##name);
62
+
63
+ #define DEF_METHOD_GET_SET(klass, name, subclass) \
64
+ klass.define_method(#name, &rb_##subclass##_get_##name); \
65
+ klass.define_method(#name "=", &rb_##subclass##_set_##name);
66
+
67
+ #define DEF_METHOD_EVENT(klass, name, subclass) \
68
+ klass.define_module_function("on_" #name "_connect", &rb_##subclass##_on_##name##_connect); \
69
+ klass.define_module_function("on_" #name "_disconect", &rb_##subclass##_on_##name##_disconnect);
70
+
71
+ #define LOG_ERROR_IF_STATE \
72
+ if (state) { \
73
+ /* callback function broke, theres not much we can do other than print out an error */ \
74
+ VALUE exception = rb_sprintf("[DiscordGameSDK] Callback function error: %" PRIsVALUE, rb_errinfo()); \
75
+ fwrite(StringValuePtr(exception), 1, RSTRING_LEN(exception), stderr); \
76
+ rb_set_errinfo(Qnil); \
77
+ }
78
+
79
+ VALUE rb_common_get_callback_proc(int args);
80
+ VALUE rb_common_get_event_proc(int args);
81
+ void rb_common_add_proc_to_hash(VALUE key, VALUE proc);
82
+
83
+ VALUE rb_result_to_obj(discord::Result);
84
+ extern VALUE rb_oPendingCallbacks;
85
+ extern VALUE rb_oProcEvents;
86
+
87
+ VALUE rb_discord_call_proc(VALUE ary);
88
+ std::function<void(discord::Result)> rb_discord_callback_wrapper_basic(VALUE proc);