Gems and diamonds
packets8 packets
The player's currencies, and the codes and prizes that add to them.
The balances live in currency.UserCurrency, indexed by SbiConstants.*_CURRENCY. They are set from the login reply (GamePlay.onWorldLogIn reads <name>Count for each of SbiConstants.CURRENCY_NAMES), then kept current by cu (ItemXtCommManager.currencyUpdateResponse) and by the answers to purchases elsewhere. A few screens also add a prize to the balance they show themselves (GemBonusSpinWheel, DailyGiftManager, PartyManager), so the client's own figure can run ahead of what the server has said.
Hearing and sending packets
What the game sends is heard on phantom.packets.client, and what the server sends on phantom.packets.server. watch hears a packet after it has gone through; on hears it first and may change or drop it; send sends one to that end. See Packets.
Overview
| Packet | Command | Way | What it is |
|---|---|---|---|
CurrencyUpdate | cu | server → game | One or more of the player’s balances changed. |
GemDonation | cd | game → server | The player donates gems. |
GemDonationResult | cd | server → game | The server says whether the donation went through. |
CurrencyExchange | ce | game → server | The player exchanges one currency for another at a shop. |
CurrencyExchangeResult | ce | server → game | The server says whether the exchange went through. |
RedeemCode | grc | game → server | The player redeems a code. |
RedeemCodeResult | grc | server → game | The server says what a redeemed code came to. |
MembershipRedeemed | grm | server → game | A membership was redeemed on the account. |
CurrencyUpdate
A balance changed (ItemXtCommManager.currencyUpdateResponse):
%xt%cu%<room>%<currency>%<amount>%<reason>% %xt%cu%<room>%100%<currency>x<amount>,<currency>x<amount>%<reason>%
amount is the new balance, not the difference. The combined form sets several crafting currencies at once (UserCurrency.setCurrency with 100). The client stores silver (8) in stone's place (7), a slip in its handler, so its own UserCurrency.getCurrency(8) lags behind this.
Fields
| Field | Type | |
|---|---|---|
currency | number | The currency that changed (CURRENCY), or 100 (COMBINED_CURRENCY) for several. |
balances | CurrencyBalance[] | The new balances: one for a single currency, any number for the combined form. |
reason | number | null | Why it changed: 15 and 16 show popups (CURRENCY_REASON), 3 and 4 announce a rise (CURRENCY_REASONS_ANNOUNCED), others change the balance quietly. Null when missing. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.CurrencyUpdate, (packet) => {
console.log(packet.currency, packet.balances, packet.reason);
});GemDonation
Donates gems (ItemXtCommManager.requestDonateGems).
Fields
| Field | Type | |
|---|---|---|
amount | number | How many gems to donate. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the game sends it to the server, after it has gone through.
const stop = phantom.packets.client.watch(packets.GemDonation, (packet) => {
console.log(packet.amount);
});GemDonationResult
Whether a donation went through (ItemXtCommManager.currencyDonationResponse): 1 if it did. The new balance arrives separately as currency.update.
Fields
| Field | Type | |
|---|---|---|
success | boolean | The donation went through: the result is 1. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.GemDonationResult, (packet) => {
console.log(packet.success, packet.extra);
});CurrencyExchange
Exchanges one currency for another at a shop (ItemXtCommManager.requestCurrencyExchange, from Shop): the shop's id, then the exchange's definition id.
Fields
| Field | Type | |
|---|---|---|
shopId | number | The shop the exchange is made at, by its id. |
exchangeDefId | number | Which exchange: its definition id, from the shop's currency exchange list (1051). |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the game sends it to the server, after it has gone through.
const stop = phantom.packets.client.watch(packets.CurrencyExchange, (packet) => {
console.log(packet.shopId, packet.exchangeDefId);
});CurrencyExchangeResult
The answer to an exchange (ItemXtCommManager.currencyExchangeResponse, then Shop.confirmPurchase): 1 if it went through, then the balance the shop sets, written as UserCurrency.setCurrency takes it (a number, or the combined form).
Fields
| Field | Type | |
|---|---|---|
success | boolean | The exchange went through: the result is 1. |
balance | string | The balance the shop sets, as UserCurrency.setCurrency takes it: a number, or the combined form <currency>x<amount>,.... Empty when missing. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.CurrencyExchangeResult, (packet) => {
console.log(packet.success, packet.balance, packet.extra);
});RedeemCode
Redeems a code (GameRedemptionXtCommManager.requestRedeemCode, from CodeRedemptionPopup):
%xt%o%grc%<room>%<code>%<captchaQuestion>%<captchaAnswer>%
Both captcha fields are empty unless both were given. In the game world the client sends this on extension o; before joining the world it uses a, which this definition does not match.
Fields
| Field | Type | |
|---|---|---|
code | string | The code, as the player typed it. |
captchaQuestion | string | The captcha the player was shown; empty unless both captcha fields were given. |
captchaAnswer | string | The player's answer to the captcha; empty unless both captcha fields were given. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the game sends it to the server, after it has gone through.
const stop = phantom.packets.client.watch(packets.RedeemCode, (packet) => {
console.log(packet.code, packet.captchaQuestion, packet.captchaAnswer);
});RedeemCodeResult
The answer to a code (GameRedemptionXtCommManager.handleRedeemCodeResponse):
%xt%grc%<room>%<result>%<details as JSON>%<hasGiftsElsewhere>%
result is a REDEMPTION_RESULT. The JSON describes what the code gave, or the captcha to show; the client passes it to the popup as parsed. hasGiftsElsewhere is set when the account has gifts waiting on another of its domains, which checkIfHasGiftInOtherDomain then tells the player about.
Fields
| Field | Type | |
|---|---|---|
result | string | What the code came to (REDEMPTION_RESULT): 1 success, negative for the failures. |
details | unknown | What the code gave, or the captcha to show, parsed from JSON. Null when empty. |
hasGiftsElsewhere | boolean | The account has gifts waiting on another of its domains. False when missing. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.RedeemCodeResult, (packet) => {
console.log(packet.result, packet.details, packet.hasGiftsElsewhere);
});MembershipRedeemed
A membership was redeemed (GameRedemptionXtCommManager.handleRedeemMembershipResponse):
%xt%grm%<room>%1%<accountType>%<daysLeft>%<subscriptionSourceType>%
Only a result of 1 is acted on: the client takes the new account type, rebuilds the HUD and reloads the avatar.
Fields
| Field | Type | |
|---|---|---|
result | number | 1 when the membership was redeemed; the client ignores any other result. |
accountType | number | null | The account's new type (2 and above is a member, Utility.isMember). Null when the result is not 1. |
daysLeft | number | null | Days left on the subscription. Null when the result is not 1. |
sourceType | string | null | Where the subscription came from, as the login reply's subscriptionSourceType. What its values mean is unknown. Null when the result is not 1. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.MembershipRedeemed, (packet) => {
console.log(packet.result, packet.accountType, packet.daysLeft);
});