{"id":426,"date":"2016-02-05T16:53:10","date_gmt":"2016-02-05T16:53:10","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=426"},"modified":"2016-02-05T16:53:10","modified_gmt":"2016-02-05T16:53:10","slug":"the-power-of-matchexpressions","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/the-power-of-matchexpressions\/","title":{"rendered":"The power of MatchExpressions"},"content":{"rendered":"<p>In this new article we are going to a take a closer look at a simple concept, that of MatchExpressions within the\u00a0SmartFoxServer SDK, and discuss why they are useful and how they can\u00a0simplify our\u00a0life when\u00a0developing multiplayer games.<!--more--><\/p>\n<h2>\u00bb What is a MatchExpression<\/h2>\n<p>MatchExpressions are used to\u00a0create conditional statements that can be applied as filters in various operations. For example searching for Users or Rooms in the server, with any\u00a0number of parameters, akin to a SQL statement for filtering records from a database.<\/p>\n<p>Interestingly, when we filter Rooms or Users via a MatchExpression we can not only use the default fields exposed by\u00a0these objects but also apply it to any user-created variable, such as RoomVariables for Rooms and UserVariables for Users.<\/p>\n<p>Let&#8217;s see a practical example. Suppose we have any number of game Rooms with these custom RoomVariables attached to them:<\/p>\n<ul>\n<li><strong>country<\/strong> (String) -&gt; indicates a game for a specific country \/ language<\/li>\n<li><strong>type<\/strong> (String) -&gt; indicates the game type<\/li>\n<li><strong>level<\/strong> (int) -&gt; indicates the player&#8217;s level required to play (e.g. 0 = beginner, 1 = pro, 2 = veteran)<\/li>\n<\/ul>\n<p>We want to search for a game of type &#8220;Chess&#8221;, in the country of Japan for a beginner player. This is how we could build our expression:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nfinal int LEVEL_ROOKIE = 0;\r\nfinal int LEVEL_PRO = 1;\r\nfinal int LEVEL_VETERAN = 2;\r\n\r\nMatchExpression exp = new MatchExpression('type', StringMatch.EQUALS, 'Chess')\r\n\t\t\t\t\t.and('level', NumberMatch.LESS_THAN, LEVEL_PRO)\r\n\t\t\t\t\t.and('country', StringMatch.EQUALS, 'Japan')\r\n<\/pre>\n<p>When can then pass this expression to the SmartFox&#8217;s API and obtain a list of all Rooms matching these conditions:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nList&lt;Rooms&gt; roomList = sfsApi.findRooms(zone.getRoomList(), exp, 0);\r\n<\/pre>\n<h2>\u00bb MatchExpressions as Room gateways<\/h2>\n<p>Another interesting use of Match Expressions is to filter out users that want to join a certain Room. The SmartFoxServer&#8217;s SDK provides a class of Rooms called <a title=\"SFS2X Game API docs\" href=\"http:\/\/docs2x.smartfoxserver.com\/AdvancedTopics\/game-api#matchExp\" target=\"_blank\">SFSGame<\/a> which allows to specify a custom MatchExpression for both players and spectators.<\/p>\n<p>This means that SFSGame Rooms will automatically deny a client JoinRequest from every\u00a0User that doesn&#8217;t match the criteria provided in those expressions.<\/p>\n<p>The MatchExpressions can be attached to any SFSGame at creation time. For example:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nCreateSFSGameSettings settings = new CreateSFSGameSettings();\r\n\r\n...\r\n...\r\n\r\n\/\/ Prepare MatchExpression\r\nMatchExpression playerExp = new MatchExpression('country', StringMatch.EQUALS, 'Japan').and('level', NumberMatch.GREATER_THAN, 0);\r\n\r\n\/\/ Attach it to Room definition\r\nsettings.setPlayerMatchExpression(playerExp);\r\n\r\n\/\/ Create Room\r\nsfs.getAPIManager().getGameApi().createGame\r\n(\r\n\tgetParentZone(),\r\n\tsettings,\r\n\tnull\r\n);\r\n<\/pre>\n<p>We highly recommend this approach to add custom join filtering to a Room without the need to add any extra server side logic\u00a0or intercepting specific server calls. Additionally these MatchExpressions can be setup from both client and server side.<\/p>\n<h2>\u00bb Additional fields beyond Variables<\/h2>\n<p>In the examples presented so far we have shown MatchExpressions targeting custom RoomVariables or UserVariables. Sometimes, however, we will need to query specific properties of a\u00a0Room or User that are not stored as Server Variables.<\/p>\n<p>For instance\u00a0we might want to query the size of a Room, the number of spectators in it, if it&#8217;s private or public etc&#8230; Similarly we may want to check if a User is a player or spectator, or if his name matches a certain pattern etc&#8230;<\/p>\n<p>For this task we can use two convenient classes (available from in both server side and client API) called <strong>UserProperties<\/strong> and <strong>RoomProperties<\/strong>, which contain fields such as:<\/p>\n<p>(RoomProperty)<\/p>\n<ul>\n<li>NAME<\/li>\n<li>GROUP_ID<\/li>\n<li>MAX_USERS<\/li>\n<li>USER_COUNT<\/li>\n<li>IS_PRIVATE<\/li>\n<\/ul>\n<p>and lot&#8217;s more. This is an example for finding all empty\u00a0game\u00a0Rooms for the game type &#8216;Poker&#8217;.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">new MatchExpression('type', StringMatch.EQUALS, 'Poker')\r\n.and(RoomProperties.USER_COUNT, NumberMatch.EQUALS, 0);<\/pre>\n<p>Here&#8217;s a more advanced example filtering all public game Rooms with free player slots for the game type &#8216;Chess&#8217;:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nnew MatchExpression('type', StringMatch.EQUALS, 'Chess')\r\n.and(RoomProperties.HAS_FREE_PLAYER_SLOTS, BoolMatch.EQUALS, true);\r\n.and(RoomProperties.IS_PRIVATE, BoolMatch.EQUALS, false);\r\n<\/pre>\n<h2>\u00bb\u00a0More usages and documentation<\/h2>\n<p>The usage of MatchExpressions doesn&#8217;t end here. We can use them in conjunction with the Game API to perform a <strong>QuickJoin<\/strong>, where the user is sent to play in the first Room matching the provided Expression.<\/p>\n<p>Also we can use &#8220;<strong>dot syntax<\/strong>&#8221; to dig into complex nested SFSObjects and SFSArrays stored as variables in Users and Rooms. For example:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">new MatchExpression(&quot;europe.italy.capital&quot;, StringMatch.EQUALS, &quot;Rome&quot;)<\/pre>\n<p>will search into a Room\/User Variable called &#8220;europe&#8221;, containing a field called &#8220;italy&#8221;, containing a field called &#8220;capital&#8221; and match it against the provided parameter.<\/p>\n<p>In order to learn all the details and see more examples we recommend checking our <a title=\"SFS2X Game API docs\" href=\"http:\/\/docs2x.smartfoxserver.com\/AdvancedTopics\/game-api\" target=\"_blank\">documentation for the Game API<\/a>\u00a0and the <a title=\"MatchExpression javadoc\" href=\"http:\/\/docs2x.smartfoxserver.com\/api-docs\/javadoc\/server\/com\/smartfoxserver\/v2\/entities\/match\/MatchExpression.html\" target=\"_blank\">relative javadoc<\/a>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this new article we are going to a take a closer look at a simple concept, that of MatchExpressions within the\u00a0SmartFoxServer SDK, and discuss why they are useful and how they can\u00a0simplify our\u00a0life when\u00a0developing multiplayer games.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[23],"tags":[55,54,32,24],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/426"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=426"}],"version-history":[{"count":11,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions"}],"predecessor-version":[{"id":437,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions\/437"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}