Skip to content

ShopModule

Max S edited this page Aug 26, 2015 · 1 revision

Shop

The Snipe server ingame shop module is based on the items module. Through the editor you can put items in a shop, limit their amount, set auto-refill flag and disable their sale. And on the server side you can make calls to get, buy or sell items. The shop contents are synchronized on the cache server so every request will be routed to there.

Using the editor is straightforward, the link to the shop is located in the top menu. The only thing that is necessary to mention here is that the editor does not edit the Shops database table directly. Instead it makes calls to cache server. When the shop contents are changed, the server saves the shop by itself. This also means that you cannot edit shop contents when the server is offline.

On the slave server side it is recommended to make snipe.slave.modules.ShopModuleCore.getDiff() calls before sending the shop contents to the client to update the local cache.

Here is the full API list of snipe.slave.modules.ShopModuleCore:

  • buy() - Sends request to cache server to buy item from shop. If the item has a limited amount, this method will check if it is still available and modify its amount.
  • getDiff() - Updates local shop contents copy from cache server. This can be called each time the client sends the request to get shop contents.
  • getItem() - Returns shop item by its ID.
  • iterator() - Returns shop items iterator.
  • sell() - Notifies cache server about user selling item.

And here is the rough sketch of ingame shop module:

class ShopModule extends snipe.slave.Module<Client, ServerTest>
{
  public function new(srv: ServerTest)
    {
      super(srv);
      name = "shop";
    }

  public override function call(client: Client, type: String, params: Params): Dynamic
    {
      var responce = null;

      if (type == "shop.get")
        responce = get(client, params);
      else if (type == "shop.buy")
        responce = buy(client, params);
      else if (type == "shop.sell")
        responce = sell(client, params);

      return responce;
    }

  function get(c: Client, params: Params)
    {
      // update shop items cache
      server.coreShopModule.getDiff();

      // make a list of shop items
      var items = new List<Dynamic>();
      for (shopItem in server.coreShopModule.iterator())
        {
          var item = shopItem.item;
          var o = item.dump(c.lang);
          o.isDisabled = shopItem.isDisabled;
          if (shopItem.amount >= 0)
            o.amount = shopItem.amount;

          items.add(o);
        }

      return { errorCode: "ok", shopItems: items };
    }

  function buy(c: Client, params: Params): Dynamic
    {
      var itemID = params.getInt("itemID");
    
      var shopItem = server.coreShopModule.getItem(itemID); 
      if (shopItem == null)
        throw "shop.buy(): item not in shop";

      if (shopItem.amount == 0)
        return { errorCode: "itemFinished" };

      if (shopItem.isDisabled)
        return { errorCode: "itemDisabled" };

      // check for money
      var item = shopItem.item;
      var price = item.attrs.getInt("price");
      if (c.money < price)
        return { errorCode: "notEnoughMoney" };

      // send request to buy to cache server
      var ret = server.coreShopModule.buy(itemID);
      if (ret != "ok")
        return { errorCode: ret };

      // try adding item to inventory
      var ret = c.user.inventory.put(item, 1);
      if (ret != "ok")
        return { errorCode : ret };
      
      // remove money
      c.money -= price;

      if (shopItem.amount > 0)
        shopItem.amount--;

      return { errorCode: "ok" };
    }

  function sell(c: Client, params: Params)
    {
      var id = params.getInt("id");

      var item = c.user.inventory.get(id);
      if (item == null)
        return { errorCode: "notInInventory" };

      var price = item.attrs.getInt("price");
      c.user.inventory.remove(item);
      c.user.money += price;

      // notify cache server
      server.coreShopModule.sell(item.id);

      return { errorCode: "ok" };
    }
}
Clone this wiki locally