rdiscord_sdk 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);