us.camin.api.Server.java Source code

Java tutorial

Introduction

Here is the source code for us.camin.api.Server.java

Source

package us.camin.api;

/*
This file is part of Caminus
    
Caminus is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
Caminus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Caminus.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.InetSocketAddress;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Scanner;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import org.json.JSONStringer;

import java.util.Random;
import org.apache.commons.codec.binary.Hex;

public class Server {
    Logger log = Logger.getLogger("Caminus.API");
    private String m_url;
    private String m_name;
    private String m_secret;

    private String genToken() {
        Random r = new Random();
        int salt = r.nextInt();
        MessageDigest crypt;
        try {
            crypt = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            log.warning("Could not find SHA-1 algorithm");
            return "";
        }
        crypt.reset();
        String token = m_name + salt + m_secret;
        crypt.update(token.getBytes());
        token = m_name + "$" + salt + "$" + Hex.encodeHexString(crypt.digest());
        log.info("Generated token " + token + " from " + m_name + salt + m_secret);
        return token;
    }

    public JSONObject exec(String path, String method, HashMap<String, String> params)
            throws MalformedURLException, ProtocolException, IOException {
        HttpURLConnection conn = open(path);
        conn.setRequestMethod(method);
        if (params.size() > 0) {
            conn.setDoOutput(true);
            Set<Map.Entry<String, String>> values = params.entrySet();
            Iterator<Map.Entry<String, String>> it = values.iterator();
            StringBuilder sb = new StringBuilder();
            while (it.hasNext()) {
                Map.Entry<String, String> param = it.next();
                sb.append(URLEncoder.encode(param.getKey(), "UTF-8"));
                sb.append("=");
                sb.append(URLEncoder.encode(param.getValue(), "UTF-8"));
                sb.append("&");
            }
            String postData = sb.substring(0, sb.length() - 1);
            conn.setFixedLengthStreamingMode(postData.length());
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            DataOutputStream out = new DataOutputStream(conn.getOutputStream());
            out.writeBytes(postData);
        }
        JSONObject ret = readJSON(conn);
        conn.disconnect();
        return ret;
    }

    public HttpURLConnection open(String path) throws MalformedURLException, IOException {
        URL authServer = new URL(m_url + path);
        HttpURLConnection conn = (HttpURLConnection) authServer.openConnection();
        conn.setRequestProperty("Authorization", "X-Caminus " + genToken());
        return conn;
    }

    public JSONObject readJSON(HttpURLConnection conn) throws IOException {
        BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
        String jsonStr;
        try {
            jsonStr = new java.util.Scanner(in).useDelimiter("\\A").next();
        } catch (java.util.NoSuchElementException e) {
            jsonStr = "";
        }
        in.close();
        try {
            JSONObject jsonObj = new JSONObject(jsonStr);
            return jsonObj;
        } catch (JSONException e) {
            throw new IOException("JSON parse error", e);
        }
    }

    // Convienence methods
    public JSONObject exec(String path, String method)
            throws MalformedURLException, ProtocolException, IOException {
        return exec(path, method, new HashMap<String, String>());
    }

    public JSONObject get(String path) throws IOException {
        return exec(path, "GET");
    }

    public JSONObject post(String path, HashMap<String, String> params) throws MalformedURLException, IOException {
        try {
            return exec(path, "POST", params);
        } catch (ProtocolException e) {
            return null;
        }
    }

    public JSONObject put(String path, HashMap<String, String> params) throws MalformedURLException, IOException {
        try {
            return exec(path, "PUT", params);
        } catch (ProtocolException e) {
            return null;
        }
    }

    public ValidationResponse validatePlayer(String name) throws IOException {
        log.info("Validating " + name + " against " + m_url);
        ValidationResponse resp = new ValidationResponse();
        JSONObject jsonObj = get("validate/" + name);
        resp.valid = jsonObj.optBoolean("valid");
        if (!resp.valid)
            return resp;

        try {
            JSONArray perms = jsonObj.getJSONArray("permissions");
            resp.permissions = new String[perms.length()];
            for (int i = 0; i < perms.length(); i++) {
                resp.permissions[i] = perms.optString(i);
            }
        } catch (JSONException e) {
            throw new IOException("JSON parse error", e);
        }

        return resp;
    }

    public Server(String url) {
        m_url = url;
    }

    public void setURL(String url) {
        m_url = url;
    }

    public void setServerName(String name) {
        m_name = name;
    }

    public void setServerSecret(String secret) {
        m_secret = secret;
    }

    public String[] fetchMOTD(String user) throws IOException {
        log.info("Fetching motd for " + user);
        String[] ret = new String[0];
        JSONObject jsonObj = get("motd/" + user);
        try {
            JSONArray motd = jsonObj.getJSONArray("motd");
            ret = new String[motd.length()];
            for (int i = 0; i < motd.length(); i++) {
                ret[i] = motd.optString(i);
            }
        } catch (JSONException e) {
            throw new IOException("JSON parse error", e);
        }
        return ret;
    }

    public double getBalance(String player) throws IOException {
        log.info("Fetching balance for " + player);
        JSONObject jsonObj = get("server/economy/" + player);
        return jsonObj.optDouble("balance", 0);
    }

    public BalanceAdjustResponse adjustBalance(String player, double delta) throws IOException {
        log.info("Adjusting balance for " + player + " by " + delta);
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("delta", "" + delta);
        JSONObject jsonObj = put("server/economy/" + player, params);
        BalanceAdjustResponse resp = new BalanceAdjustResponse();
        resp.success = jsonObj.optBoolean("success", false);
        resp.newBalance = jsonObj.optDouble("balance", 0);
        resp.message = jsonObj.optString("message", "");
        return resp;
    }

    public boolean pingAPI() {
        log.info("Pinging API server to verify credentials");
        JSONObject response;
        try {
            response = get("server/whoami");
        } catch (IOException e) {
            log.log(Level.SEVERE, "Could not ping API server.", e);
            return false;
        }
        log.info("Connected to server running " + response.optString("server-version") + ", api "
                + response.optInt("api-version"));
        return response.optInt("api-version") == 2;
    }

    public void closeSession(String player) throws IOException {
        log.info("Closing session for " + player);
        get("server/session/" + player + "/close");
    }

    public void notifyEventHandled(ServerEvent event) throws IOException {
        log.info("Closing event " + event.id);
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("job", Integer.toString(event.id));
        post("server/events", params);
    }

    public void sendEvents(ClientEvent[] event) throws JSONException, IOException {
        log.info("Submitting events");
        JSONStringer out = new JSONStringer();
        out.object();
        out.key("events");
        out.array();
        for (ClientEvent evt : event) {
            out.value(evt.toJSON());
        }
        out.endArray();
        out.endObject();
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("events", out.toString());
        put("server/events", params);
    }

    public ServerEvent[] pollEventQueue() throws IOException {
        log.info("Polling server for events");
        JSONObject jsonObj = get("server/events");
        JSONArray eventList;
        try {
            eventList = jsonObj.getJSONArray("events");
        } catch (JSONException e) {
            return new ServerEvent[0];
        }

        ServerEvent[] events = new ServerEvent[eventList.length()];
        for (int i = 0; i < eventList.length(); i++) {
            try {
                events[i] = ServerEvent.fromJSON(eventList.getJSONObject(i));
            } catch (JSONException e) {
                log.log(Level.SEVERE, "Bad JSON", e);
                events[i] = null;
            }
        }
        return events;
    }

    public ValidationResponse openSession(String player, InetSocketAddress sourceAddr) throws IOException {
        log.info("Opening session for " + player);
        ValidationResponse resp = new ValidationResponse();
        HashMap<String, String> params = new HashMap<String, String>();
        //params.put("ip", sourceAddr.toString());
        params.put("ip", "");
        JSONObject jsonObj = post("server/session/" + player + "/new", params);
        resp.valid = jsonObj.optBoolean("success");
        resp.errorMessage = jsonObj.optString("error");
        resp.sessionId = jsonObj.optInt("sessionId");
        try {
            JSONArray perms = jsonObj.getJSONArray("permissions");
            resp.permissions = new String[perms.length()];
            for (int i = 0; i < perms.length(); i++) {
                resp.permissions[i] = perms.optString(i);
            }
        } catch (JSONException e) {
            throw new IOException("JSON parse error", e);
        }
        return resp;
    }

    public PlayerVaultSlot[] loadVault(String player) throws IOException {
        log.info("Opening vault for " + player);
        PlayerVaultSlot[] vault;
        JSONObject jsonObj = get("server/vault/" + player);
        try {
            JSONArray items = jsonObj.getJSONArray("items");
            vault = new PlayerVaultSlot[items.length()];
            for (int i = 0; i < items.length(); i++) {
                JSONObject slot = items.getJSONObject(i);
                vault[i] = new PlayerVaultSlot();
                vault[i].item = slot.optInt("item");
                vault[i].quantity = slot.optInt("quantity");
                vault[i].damage = (short) slot.optInt("damage");
                vault[i].data = (byte) slot.optInt("data");
                vault[i].position = slot.optInt("position");
            }
        } catch (JSONException e) {
            throw new IOException("JSON parse error", e);
        }
        return vault;
    }

    public void saveVault(String player, PlayerVaultSlot[] vault) throws IOException, JSONException {
        log.info("Saving vault for " + player);
        JSONStringer out = new JSONStringer();
        out.object();
        out.key("items");
        out.array();
        for (PlayerVaultSlot item : vault) {
            out.object();
            out.key("item").value(item.item);
            out.key("quantity").value(item.quantity);
            out.key("damage").value(item.damage);
            out.key("data").value(item.data);
            out.key("position").value(item.position);
            out.endObject();
        }
        out.endArray();
        out.endObject();
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("contents", out.toString());
        put("server/vault/" + player, params);
    }
}