128 lines
4.9 KiB
TypeScript
128 lines
4.9 KiB
TypeScript
import compression from "compression";
|
|
import express, { NextFunction, Request, Response } from "express";
|
|
import logger from "debug";
|
|
|
|
import gameLogin from "./gameLogin";
|
|
import gameLogout from "./gameLogout";
|
|
import getGameCharge from "./getGameCharge";
|
|
import getGameEvent from "./getGameEvent";
|
|
import getGameIdlist from "./getGameIdlist";
|
|
import getGameMessage from "./getGameMessage";
|
|
import getGameRanking from "./getGameRanking";
|
|
import getGameSale from "./getGameSale";
|
|
import getGameSetting from "./getGameSetting";
|
|
import getUserActivity from "./getUserActivity";
|
|
import getUserCharacter from "./getUserCharacter";
|
|
import getUserCharge from "./getUserCharge";
|
|
import getUserCourse from "./getUserCourse";
|
|
import getUserData from "./getUserData";
|
|
import getUserDataEx from "./getUserDataEx";
|
|
import getUserDuel from "./getUserDuel";
|
|
import getUserItem from "./getUserItem";
|
|
import getUserMap from "./getUserMap";
|
|
import getUserMusic from "./getUserMusic";
|
|
import getUserOption from "./getUserOption";
|
|
import getUserOptionEx from "./getUserOptionEx";
|
|
import getUserPreview from "./getUserPreview";
|
|
import getUserRecentRating from "./getUserRecentRating";
|
|
import getUserRegion from "./getUserRegion";
|
|
import upsertClientBookkeeping from "./upsertClientBookkeeping";
|
|
import upsertClientDevelop from "./upsertClientDevelop";
|
|
import upsertClientError from "./upsertClientError";
|
|
import upsertClientSetting from "./upsertClientSetting";
|
|
import upsertClientTestmode from "./upsertClientTestmode";
|
|
import upsertUserAll from "./upsertUserAll";
|
|
import createSqlWrapper from "../sql";
|
|
import { DataSource } from "../../sql";
|
|
|
|
const debug = logger("app:chuni:io");
|
|
|
|
// Thankfully we can use standard middleware for JSON I/O. We have to use a
|
|
// zlib middleware as well because compression is non-optional: the client will
|
|
// attempt to inflate whatever response we send to it whether there's a
|
|
// Transfer-Encoding header or not.
|
|
|
|
function quirks(req: Request, res: Response, next: NextFunction) {
|
|
// Chunithm client does not follow the HTTP spec: user agents must indicate
|
|
// that they are willing to accept a particular Transfer-Encoding for that
|
|
// T-E to be used (unless the T-E in question is "chunked" but w/e), and this
|
|
// indication is advisory anyway, the server is permitted to ignore it.
|
|
//
|
|
// Force this header into the request, since it is not present normally.
|
|
|
|
// ... unless, that is, the client is actually somebody debugging with curl
|
|
// and not the real game client, in which case this forced deflate can be
|
|
// annoying. Pass an "X-Debug" request header to suppress forced compression.
|
|
|
|
if (req.headers["x-debug"] === undefined) {
|
|
req.headers["accept-encoding"] = "deflate";
|
|
}
|
|
|
|
return next();
|
|
}
|
|
|
|
function trace(req: Request, res: Response, next: NextFunction) {
|
|
debug("\n--- Chunithm %s ---\n", req.url);
|
|
debug("Request: %j", req.body);
|
|
|
|
const prevJson = res.json;
|
|
|
|
res.json = function(obj) {
|
|
debug("Response: %j", obj);
|
|
|
|
res.json = prevJson;
|
|
res.json.apply(this, arguments);
|
|
|
|
return res;
|
|
};
|
|
|
|
return next();
|
|
}
|
|
|
|
export default function chunithm(db: DataSource) {
|
|
const wrapper = createSqlWrapper(db);
|
|
|
|
wrapper.rpc("/GameLoginApi", gameLogin);
|
|
wrapper.rpc("/GameLogoutApi", gameLogout);
|
|
wrapper.rpc("/GetGameChargeApi", getGameCharge);
|
|
wrapper.rpc("/GetGameEventApi", getGameEvent);
|
|
wrapper.rpc("/GetGameIdlistApi", getGameIdlist);
|
|
wrapper.rpc("/GetGameMessageApi", getGameMessage);
|
|
wrapper.rpc("/GetGameRankingApi", getGameRanking);
|
|
wrapper.rpc("/GetGameSaleApi", getGameSale);
|
|
wrapper.rpc("/GetGameSettingApi", getGameSetting);
|
|
wrapper.rpc("/GetUserActivityApi", getUserActivity);
|
|
wrapper.rpc("/GetUserCharacterApi", getUserCharacter);
|
|
wrapper.rpc("/GetUserChargeApi", getUserCharge);
|
|
wrapper.rpc("/GetUserCourseAPi", getUserCourse);
|
|
wrapper.rpc("/GetUserDataApi", getUserData);
|
|
wrapper.rpc("/GetUserDataExApi", getUserDataEx);
|
|
wrapper.rpc("/GetUserDuelApi", getUserDuel);
|
|
wrapper.rpc("/GetUserItemApi", getUserItem);
|
|
wrapper.rpc("/GetUserMapApi", getUserMap);
|
|
wrapper.rpc("/GetUserMusicApi", getUserMusic);
|
|
wrapper.rpc("/GetUserOptionApi", getUserOption);
|
|
wrapper.rpc("/GetUserOptionExApi", getUserOptionEx);
|
|
wrapper.rpc("/GetUserPreviewApi", getUserPreview);
|
|
wrapper.rpc("/GetUserRecentPlayerApi", getUserRecentRating);
|
|
wrapper.rpc("/GetUserRecentRatingApi", getUserRecentRating);
|
|
wrapper.rpc("/GetUserRegionApi", getUserRegion);
|
|
wrapper.rpc("/UpsertClientBookkeepingApi", upsertClientBookkeeping);
|
|
wrapper.rpc("/UpsertClientDevelopApi", upsertClientDevelop);
|
|
wrapper.rpc("/UpsertClientErrorApi", upsertClientError);
|
|
wrapper.rpc("/UpsertClientSettingApi", upsertClientSetting);
|
|
wrapper.rpc("/UpsertClientTestmodeApi", upsertClientTestmode);
|
|
wrapper.rpc("/UpsertUserAllApi", upsertUserAll);
|
|
|
|
const app = express();
|
|
|
|
app.use(quirks);
|
|
app.use(compression({ threshold: 0 }));
|
|
app.use(express.json({ limit: "50mb" })); // that ought to be enough
|
|
app.use(trace);
|
|
|
|
app.use("/ChuniServlet", wrapper);
|
|
|
|
return app;
|
|
}
|