---
title: "Guild"
disqus: hackmd
tags: 'ctrl'
---
## Chapter 6 Guild Management
### 6-1 Guild
A guild is the players’ group in the game, which allows players to connect and communicate with one another. Different from the scenes, the objects, and the leaderboard, a guild does not have an object frame of class or instance, so it does not need a backstage management category base like the scenes, the objects, and the leaderboard. However, it still needs executive authorization for the api that is related to management and safety.
A guild is an important tool to keep players dependent on the game, and some special ways of playing the game are accessible only after joining a guild. Cloud’s guild api focuses on the management on the guild and its members. Developers can utilize the registers and the `tag` attribute in the guild and in the members’ data to define what these data mean for the players, in order to open or close some game functions or to record the attribute values of these functions.
**Guild Members’ Roles**
There are three kinds of roles a player may play in the guild, and the role is related to its executive authorization. There will be a further explanation in the later chapters.

**Guild Management Program**
The API functions for guild management are in the CloudGuild category, and this category is composed of static functions, with neither Constructor nor Property. When program designers want to deal with something related to the objects, please call these functions directly.
For the next API function we are going to introduce, take the `CreateGuild()` from the next session for example, program designers have to add “CloudGuild.” at the beginning when calling, and it will look like this: CloudGuild.CreatGuild().
### 6-2 Creating and Deleting a Guild
To build a guild, one needs to call the CreateGuild() function in the game function, and here is what its definition is:
```
csharp
public static void CreateGuild(CloudGame game, string name, string note, int maxmember, int permission, int tag,
int G1, int G2, int G3, int G4, OnCallCompletionWithData cb, object token)
```
(1) `name` The name of the created guild. If developers want to set limits for the guilds’ names due to the game’s planning, please design a user interface that filters the names. There are no limitation for this parameter.
(2) `note` The description words for the created guild.
(3) `maxmember` To designate the maximum capacity of players (the max value is 100.)
(4) `permission` To designate who can join the guild. 0: Anyone can join the guild. 1: Only guild managers or super users have the authorization to decide whether the player can join the guild.
(5) `tag` The guild’s tags。
(6) `G1~G4` To designate the guild’s register value, and the meaning that the registers stand for in the game can be defined by developers flexibly.
cb is the callback function after finishing API, and here is its definition:
void cb(int code, object obj, object token)
When the code is 0, the setting succeeds.
When the code is not 0, the setting fails and the code is the error code.
obj when code=0, (uint) obj saves the guild’s verification code.
When the code is not 0, obj is meaningless and negligible.
After creating the guild, the caller is the guild president, who has the authorization to change the guild’s basic information, delete the guild and manage the guild members’ authorizations. If a player is already the member of aother guild, whether as a normal member, manager, or president, he cannot create a new guild.
If the president wishes to not continue the guild’s existence, he can call the `DeleteGuild ()` function and here is its definition:
public static void DeleteGuild(CloudGame game, OnCallCompletion cb, object token)
After deleting the guild successfully, the callback’s `code` parameter’s value is 0. Otherwise, the code is not 0 when there is an error.
**Executive Authorization**
This function can only be called by the president. If other managers or normal players try to call it, callback’s code parameter will send back an error code that stands for an authorization error.
If developers decided that creating and deleting a guild have to be done in the server’s logic, the DP program has to call `suCreateGuild()` and `suDeleteGuild()`. When calling, so designate the guildid, which is the guild’s verification code, or callback will send back an authorization error.
**Change Guild’s Information**
After creating the guild, only the president can change its information, such as the guild’s name, description, its openness, and so on. In practice, developers have to make UI in the game program to let the player (the guild president) enter the information that needs to be updated and to call `UpdateGuild()` to process the updating.
However, there is one thing developers should be aware of. To maintain the game’s safety and fairness, some data in the guild are related to the competition among players, such as the guild registers that record the guilds’ levels, achievements, and so on. It is better to not allow changing those data from the user-edge program but from the DP server’s logic with `suUpdateGuild()` to avoid providing access to plug-ins.
### 6-3 List the Guild Data of the Created Data
At the beginning of processing the game program, it is necessary to know which are the created guilds. Here are some different listing functions that can list the guilds the player wants to see according to different needs.
| function’s name | note |
| :------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| GetGuild | the regular search enumeration |
| GetGuildByName | 依Search with the guild’s name. The parameter `name` that sends in when calling is the keyword one wants to search with. **Please be aware** that the guild that has the exact same name as the guild data parameter `name` sends back will be listed as the first element in the sent back `List <Hashtable>`. Therefore, if one only wants to find the guild with the name that fits exactly, please set the parameter `maxmmber=1` . |
| GetGuildByPermission | Search with the guild’s openness and designate the value of parameter `permssion` to select the types that are listed: 0: anyone can join, 1: only the president or the manager’s approval allows joining, and 2: no one can join. |
| GetGuildByTag | Search with the guild’s `Tag` value |
| GetGuildByUserid | Search with player’s `userid` and find the guild he joins. Since a player can join one guild at most, this function will send back one guild data at most. |
**Guild Data**
After calling, the listed guild data is sent back with `List <Hashtable>` by callback function, and every Hashtable element in the list is a guild data. Below are the key values that store the guild data:
| Key | Value | Type |
| :----------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----: |
| guildid | guild’s verification code | int |
| name | guild’s name | string |
| note | guild’s note | string |
| leader | guild president’s nickname | string |
| maxnumber | the maximum number (of players) the guild allows | int |
| playernumber | the current total number (of players) in the guild | int |
| tag | guild’s tags | int |
| permission | guild’s openness: 0: anyone can join, 1: only the president or the manager’s approval allows joining, and 2: no one can join. | int |
| g1 | register G1, whose attribute is defined by the developers | int |
| g2 | register G2, whose attribute is defined by the developers | int |
| g3 | register G3, whose attribute is defined by the developers | int |
| g4 | register G4, whose attribute is defined by the developers | int |
| g1stamp | the last time the G1 register is updated | string |
| g2stamp | the last time the G2 register is updated | string |
| g3stamp | the last time the G3 register is updated | string |
| g4stamp | the last time the G4 register is updated | string |
| createtime | the time the guild is created | string |
| applystate | The caller’s application status on joining the guild: 0: has not applied yet or no data found (Since the application is not kept permanently, it will be shown as no data after deleting.), 1: examining by the guild manager, 2: application approved, or 3: application is rejected. | int |
**Ranking Order**
Every guild has four registers, G1, G2, G3, and G4, which store four integer data.
The design of registers allows game developers to use them flexibly and define their use. When calling the functions that are related to `GetGuild()`, the guilds’ order can be ranked by the registers’ values.
For example, we can define G1 as the guild’s level, and when the player selects the guild, the game program will put the guilds with higher levels in the front. When calling `GetGuild()`, here is the designated parameter `OrderBy`:
```
csharp
String OrderBy="g1 desc";
```
Or use several registers and the time the guild is created as the ranking order, which are separated with a “,”
```
csharp
String OrderBy="g1 desc, g2 asc, createtime asc";
```
**Conditional Filtering**
When searching listed guild data, sometimes one only want to list some of the guilds that meet the conditions due to the player’s level or other reasons. `GetGuild()` can set up conditions with parameters when being called.
The filtering conditions can be the registers’ values and/or the time the guild is created. The register filtering can also be a logic equation, such as setting G1 as the guild’s level and G2 as the guild’s fighting ability, and here is how the register filtering can be designated:
```
csharp
String RegisterCondition="2<g1<5 and 10>g2";
```
In this way, the guilds that have a level between 2 to 5 and a fighting ability less than 10 are listed.
**Other Parameters**
There are many overloadings of functions that are related with `GetGuild()` and there are all kinds of parameters, according to different needs. Here is the explanation for all the parameters:
- `orderby`
Rank the control string, which can be ranked with designated register values or the time the guild is created. Below are the keywords and an additional suffix asc or desc can demonstrate an increasing or decreasing order. If the suffix is not designated, it is preset as asc:
| Keyword | note |
| :--------: | :----------------: |
| g1 | ranked with the G1 register’s value |
| g2 | ranked with the G2 register’s value |
| g3 | ranked with the G3 register’s value |
| g4 | ranked with the G4 register’s value |
| createtime | with the time the guild is created |
Example: ”`g1 desc`”
If there are more than one ranking conditions, please use a “,” to separate them, such as: ”`g1 asc,g3 desc,createtime desc`”
- `MaxNumber`
Designate the maximum number of data one can read.。
**Please be aware** that `GetGuildByName()` performs the keyword search on names with parameter `name`, and the one with the exact same name will be listed first. Therefore, if one only wants to obtain the guild with the exact same name, please set `MaxNumber = 1`.
- `RegiterCondition`
Designate register conditions and send back the list of guilds that meet the conditions. The condition equations are composed with “>,” “<,” “=,” “<=,” “>=,” “and,” “or,” and more, such as ” 2<g1<5 and 10>g2 or g3=5 and 1<g4 <50”.
- `Start`
list the guilds that are created later than this time
- `End`
list the guilds that are created earlier than this time
### 6-4 Guild Member Management
To let players join a guild in the middle of the game, the UI can be designed as below:

The guild’s data are obtained with functions that are related to `GetGuild`. When the sent back the key value of ”`applystate`” in the guild Hashtable is 0, the “I want to join” button can be shown. In the above picture, the “sent” is the result of having the key of ”`applystate`” as 1. After the player clicks it, there are two ways the game program can let the player join the game:
1. Join Directly
If the guild’s openness is set to let anyone join it, the game program can call `JoinGuild()` directly and let the player join the guild. The value of parameter `guildid` is set to be the identification code of the guild he wants to join, which can be obtained with `GetGuild()` when it lists the guild data, as mentioned in the previous sesion.
2. Join After Approval
If the player needs approval from the guild president or the manager, the game program needs to provide a sub-system on member management. Here are some api functions that can help the game program build a complete process of applying for a guild and approving applications. Except for the interface that allows non-developers to search for guilds, which we introduce earlier, after the player selects the guild he wants to join and sends out the application, guild managers also need a recruitment interface like this to show the application on joining the guild.

At this moment, non-member players cannot call api to join the guild as well. Under Cloud’s authorization monitoring, there is no need of worrying about players using illegal programs to join the guild without permission when the president set the openness as permission=1 upon creating the guild.
To understand the process of applying for the guild and approving the application more easily, we will explain with steps 1-11 in the below picture, and developers can write them into the game program accordingly. The final steps, step 12 and 13, are used when the guild manager approves or rejects a player’s application. In this situation, we return to the most basic in-time communication systems, CloudScene and CloudGame, and notify the player with scenes or private messages. Or we can use CloudMailbox to send offline messages to the player.

**List Guild Members**
In any situation, when one wants to show the members in a guild, just call `GetGuildMemebr()`, and callback will send back `List Hashtable`. Every hashtable saves a member data, and the Key/Value are listed:
| Key | Value | Type |
| :-------: | :---------------------------------------------------------------------: | :----: |
| guildid | guild’s indentification code | int |
| userid | player’s userid | String |
| nickname | player’s nickname | String |
| online | 0: player is not online Not 0: poid of the online plsyer | uint |
| privilege | member’s authorization in this guild 0: normal memer, 1: (privileged member) manager, or 2: (privileged member) president | int |
| r1 | register R2, and developers can define its attribute | int |
| r2 | register R3, and developers can define its attribute | int |
| r3 | register R4, and developers can define its attribute | int |
| r4 | register R4, and developers can define its attribute | int |
| r1stamp | the last time the R1 register is changed | String |
| r2stamp | the last time the R2 register is changed | String |
| r3stamp | the last time the R3 register is changed | String |
| r4stamp | the last time the R4 register is changed | String |
| jointime | the time the player joins the guild | String |
There are also many overloadings for this function, and they are decided by whether there are the parameters:
- `guildid`
Designate the identification code of the guild one wants to read. If it is not designated, send back the guild that the player who calls this function joins.
- `orderby`
After calling, the order of the sent-back list of guild members is a parameter shown with strings, which can be ranked with the registers’ value and the time the player joins the guild, because there are four guild registers (and their meanings are defined by the developers according to the game’s need. For more information, please go to `JoinGuild()`.)
In this parameter string, here are the several the Keywords we can use. Also, one can add suffix asc or desc to show whether it’s an increasing or a decreasing order. If the suffix is not designated, it is preset as asc:
| Key | note |
| :------: | :----------------: |
| r1 | ranked with register R1’s value |
| r2 | ranked with register R2’s value |
| r3 | ranked with register R3’s value |
| r4 | ranked with register R4’s value |
| jointime | with the time the player joins the guild |
Example: ”`r1 desc`”
If there are more than one ranking conditions, please use a “,” to separate them, such as: ”`r1 asc,r3 desc, jointime desc`”
- `RegiterCondition`
Designate register conditions and send back the list of guilds that meet the conditions. The condition equations are composed with「>」、「<」、
「=」、「<=」、「>=」、「and」、「or」,
such as: ”` 2<r1<5 and 10>r2 or r3=5 and 1<r4 <50`”
(In different overloadings, this parameter is not always provided. If not, the register condition is not filtered.)
- `Start`
list the guilds that are created later than this time (starting time)
(In different overloadings, this parameter is not always provided. If not or is null, there is no starting time.)
- `End`
list the guilds that are created earlier than this time(ending time)
(In different overloadings, this parameter is not always provided. If not or is null, there is no ending time.)
**Setting and Removing Guild Manager’s Purview**
A manager is someone who, other than the guild president, can help review member recruiting. President’s game program can set a member, who already joins the guild, as the manager with `SetGuildManager()`, and a SuperUser uses `suSetGuildManager()`. Afterward, this manager has the power to approve or reject other players’ applications on joining the guild.
For players who are already managers, members or Super Users can also use the same function `SetGuildManager()` and `suSetGuildManager()` to remove their purviews.
**Member Withdrawing from the Guild**
When a member withdraws from a guild voluntarily or when the president or the manager wants to kick a player out of the guild, they can call `LeaveGuild()` and a Super User can call `suLeaveGuild()`.
**Set Member Registers’ Values**
When members join the guild, they voluntarily own a set of registers, which are R1, R2, R3, and R4. For these four registers that can store int integers, there are two ways to set their values:
1. directly call the api function that set registers’ values
`SetPlayerGuildRegister()`.Here is the function’s definition:
:
```
csharp
static void SetPlayerGuildRegister(CloudGame game,
object R1, object R2, object R3, object R4,
OnCallCompletion cb, object token)
```
The registers parameters R1~R4 want to set have to be integers. If one does not want to set them, send null.
Please be aware that if players can set their own guild registers, the purview has to be turned on in the management backstage. Or else, only a Super User can set them in DP with `suSetPlayerGuildRegister()`.
2. set synchronously when calling `SetItemInstanceAttribute()`
Use the `SetItemInstanceAttribute()` overloading function that writes synchronously in registers R1, R2, R3, and R4. These overloadings have additional string parameters of designated registers’ names, which represent the registers they want to write synchronously in.
When writing in only one attribute, call like this:
```
csharp
CloudItem.SetItemInstanceAttribute(game, iguid, id, attrName, attrValue, "r2", cb, null);
```
Representing writing synchronously in caller’s R2 register.
If one is a Super User, please designate an userid and call `suSetItemInstanceAttribute()`.
Also, if one wants to write in several attribute values at once, show the registers that one wants to write synchronously in with string arrays when using string arrays to designate attributes’ name and values, such as below:
```
csharp
String[] attrName={"name","grade","class","enegy","point"};
String[] attrValue={"Bruce","3230","A300","98723","1381"};
String[] SyncR={null,null,null,"r3","r1"};
CloudItem.SetItemInstanceAttribute(game, iguid, id, attrName, attrValue, SyncR, cb, null);
```
From parameter SyncR’s string value, “r3” and “r1” respectively correspond to “`enegy`” and “`point`,” so when attribute value “`98723`” is written into “`enegy`,” integer `98723` is written in the R3 register synchronously. Similarly, when attribute value “`1381`” is written into “`point`,” integer `1381` is written in the R1 register synchronously.
### 6-5 Mailbox
Mailbox messages are also called “offline messages.” Different from CloudScene and CloudGame’s in-time messages, they are used for game programs to send non-in-time messages to other players. The sent messages are stored in the cloud first and take up space in the game’s storage capacity, but the system does not notify the receiver automatically. Developers have to produce program code for in-time notifications with private messages or scene messages.
Since messages are stored in the Cloud cloud storage device, if developers want to save more space, they can download the message in the game program, save it in the player’s local storage, and then delete the read message. Afterward, when the player game program is started, if one wants to list the messages, he has to read the read messages in the local edge, read cloud messages with api, store them in the local after reading them, and delete them. So on and so forth, until the player’s message base is empty.
Offline messages are handled with a dedicated api class CloudMailbox, and the functions in them are static. Receiving and sending messages are really simple, and here are the functions:
| function’s name | explanation |
| :----------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| Sendmail() | Send messages and decide to send to: 1. A normal users, and use the parameter to designate receiver’s `userid`. 2. A guild member, and use the parameter to designate guild’s `guildid`, and designate another parameter defined as `enum_Whom_` to designate who the receiver is. Here is the definition of *Whom*: `enum _Whom_ { all = 1, manager = 2, leader = 3 };`. Besides, a self-defined tag value can also be designated upon sending to let the receiver filter according to the tags. |
| Listmail() | List the messages in the mailbox, which means reading the messages in mailbox. |
| DeleteMail() | Delete the messages. |
| SetMailTag() | Set the tag value of a certain message. |
Explanation:
all: all members of the guild, manager: the guild’s managers (including the president), and leader: the guild’s president.
**Sending Messages**
1. Send to normal users:
```
csharp
void SendMail(CloudGame game,string touserid, int tag, string text, bool hasSentBackup,
OnCallCompletionWithData cb, object token)
```
- touserid:user id receiver’s user id
- tag:mail’s tag, which can be set as a filtering condition when reading the mail list
- text:mail’s content, only plane texts are allowed and the maximum length is 1K units
- hasSentBackup true:After sending the message, the sender gets a copy of it as well. The mail copy’s mailid will be sent back in callbackcb’s data parameter.
2. Send to guild members:
```
csharp
void SendMail(CloudGame game, int guildid, _Whom_ whom, int tag, string text, bool hasSentBackup,
OnCallCompletionWithData cb, object token)
```
- `guildid`: guild’s identification code, and send the message to the member of this guild
- `whom`:Designate who of the guild members the message is sending to, and here is the definition: num _Whom_ {all=1, manager=2, leader=3} Explanation: all: send to all members of the guild, manager: the guild’s managers, and leader: the guild’s president.
- `tag`:mail’s tag, which can be set as a filtering condition when reading the mail list
- `text`:mail’s content, only plane texts are allowed and the maximum length is 1K units
- `hasSentBackup`:true:After sending the message, the sender gets a copy of it as well. The mail copy’s mailid will be sent back in callbackcb’s data parameter. false: Do not store the mail copy.
**Reading Messages**
There are six overloadings for reading mailbox messages.
```
void ListMail(CloudGame game, int mailid, OnCallCompletionWithData cb, object token)
void ListMail(CloudGame game, Folder folder, OnCallCompletionWithData cb, object token)
void ListMail(CloudGame game, Folder folder, int tag, OnCallCompletionWithData cb, object token)
void ListMail(CloudGame game, Folder folder, DateTime start, DateTime end, OnCallCompletionWithData cb, object token)
void ListMail(CloudGame game, Folder folder, int tag, DateTime start, DateTime end, OnCallCompletionWithData cb, object token)
void ListMail(CloudGame game, Folder folder, int tag, DateTime datetime, Direction direction, OnCallCompletionWithData cb, object token)
```
There are different ways of reading according to the below parameters:
- `mailid`:Designate the mailid and read the message directly.
- `folder`:Designate the folder, and there are three enum values. The definition is enum _Folder_ {sent=1, inbox=2, both=3 }. Explanation: sent: mail copy folder, inbox: inbox, and both: both.
- `tag`:Designate the tag, which is defined by the developers themselves.
- `start`,` end`:Designate the starting and ending time and read the messages that are sent between these two times.
- `datetime`, `direction`:Designate the time and direction and read the messages sent before or after this time. There are two `enum` values for `direction`, and here are their definitions: enum _Direction_ {before = 1, after = 2 }. Explanation: `before`: delete the messages before datetime, and `after`: delete the messages after datetime.
The read mails are sent back with callback’s parameter cb. When `code=0`, which means it is successful, the data of the read mail list is stored in parameter `data` as `List Hashtable`, and the Key/Value are listed:
| Key | Value | Type |
| :----------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----: |
| mailid | mail’s idntification code Mail ID | int |
| text | mail’s content | String |
| folder | mail’s location, 1: mail copy and 2: inbox | int |
| touserid | Folder =2 (inbox): Receiver’s userid. Folder=1 (mail copy): 1. When the first character of the string is “#,” the receiver is a guild member and the string behind the “#” us the guild’s identification code. 2. When the first character of the string is not "#," it is the receiver’s userid. | String |
| tonickname | Folder =2 (inbox): Receiver’s nickname. Folder=1 (mail copy): 1. When sent to a guild member, it is the guild’s name. 2. When send to an individual player, it is the receiver’s userid. | String |
| fromuserid | sender’s userid | String |
| fromnickname | sender’s nickname | String |
| senddate | the time it is sent | String |
| tag | | int |