org.ramidore.logic.system.GuildBattleLogic.java Source code

Java tutorial

Introduction

Here is the source code for org.ramidore.logic.system.GuildBattleLogic.java

Source

/*
 * Copyright 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ramidore.logic.system;

import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.ramidore.Const;
import org.ramidore.bean.GvLogTable;
import org.ramidore.core.PacketData;
import org.ramidore.util.RamidoreUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * GV????.
 *
 * @author atmark
 */
public class GuildBattleLogic extends AbstractSystemMessageLogic {

    /**
     * Logger.
     */
    private static final Logger LOG = LoggerFactory.getLogger(GuildBattleLogic.class);

    /**
     * ???.
     * <p>
     * 1?????
     */
    private static final String UNIT_PATTERN = "380069120000(..)00(....)0000(....)0000(....)0000"
            + Const.BASE_PATTERN + "00(?:CC)*" + Const.BASE_PATTERN + "00(?:CC)*";

    /**
     * ?????.
     */
    private static final String PATTERN = "^(?:.{2})+(" + UNIT_PATTERN + ")(?:.{2})*$";

    /**
     * ?????.
     */
    private static final String START_PATTERN = "^..002811CDCDCDCD..00000008001012000001FF58006A120000"
            + Const.BASE_PATTERN + "00(?:CC)+" + Const.BASE_PATTERN + "00(?:CC)+0000000000000000CDCDCCCC(?:.{2})*$";

    /**
     * ??????.
     */
    private static final String RESULT_PATTERN = "4400F1110000(....)" + Const.BASE_PATTERN
            + "00(?:.{2})+(?:CC)+(?:....)CCCC....0000..00(..)00(..)00(..)00(....)(..)00..00CCCC";

    /**
     * ???????.
     */
    private static final String NAME_PATTERN = "FFFFFFFFCCCC" + Const.BASE_PATTERN + "00(?:CC)+";

    /**
     * ??.
     */
    private static Pattern unitPattern = Pattern.compile(UNIT_PATTERN);

    /**
     * ??.
     */
    private static Pattern pattern = Pattern.compile(PATTERN);

    /**
     * ??.
     */
    private static Pattern startPattern = Pattern.compile(START_PATTERN);

    /**
     * ??.
     */
    private static Pattern resultPattern = Pattern.compile(RESULT_PATTERN);

    /**
     * ??.
     */
    private static Pattern namePattern = Pattern.compile(NAME_PATTERN);

    /**
     * .
     */
    private Date startDate = null;

    /**
     * ????.
     */
    private Set<String> nameSet;

    /**
     * K/D???.
     */
    private Set<String> killDeathNameSet;

    /**
     * ??.
     */
    private DuplicateChecker dupChecker;

    /**
     * ??.
     */
    private PointChecker pointChecker;

    /**
     * ??.
     * <p>
     * ????
     */
    @Getter
    private ConcurrentLinkedQueue<GvLogTable> logDataQ;

    /**
     * ?.
     */
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss");

    /**
     * .
     */
    public GuildBattleLogic() {

        logDataQ = new ConcurrentLinkedQueue<GvLogTable>();

        nameSet = new HashSet<String>();
        killDeathNameSet = new HashSet<String>();

        logDataQ.clear();

        dupChecker = new DuplicateChecker();
        pointChecker = new PointChecker();
    }

    @Override
    public boolean execute(PacketData data) {

        /* ?????? */

        Matcher nameMatcher = namePattern.matcher(data.getStrData());

        // ????????
        // ????????????????
        if (startDate != null && nameMatcher.find()) {

            String name = RamidoreUtil.encode(nameMatcher.group(1), Const.ENCODING);

            nameSet.add(name);
        }

        /* ?????? */

        Matcher matcher = pattern.matcher(data.getStrData());

        if (matcher.matches()) {

            if (startDate == null) {
                // ?????????????????

                startDate = data.getDate();
            }

            Matcher unitMatcher = unitPattern.matcher(data.getStrData());

            while (unitMatcher.find()) {

                int order = RamidoreUtil.intValueFromAscHexString(unitMatcher.group(1));
                int point = RamidoreUtil.intValueFromDescHexString(unitMatcher.group(2));
                int point0 = RamidoreUtil.intValueFromDescHexString(unitMatcher.group(3));
                int point1 = RamidoreUtil.intValueFromDescHexString(unitMatcher.group(4));
                String srcName = RamidoreUtil.encode(unitMatcher.group(5), Const.ENCODING);
                String dstName = RamidoreUtil.encode(unitMatcher.group(6), Const.ENCODING);

                if (!dupChecker.check(data.getDate(), point0, point1)) {

                    continue;
                }

                // ??????
                killDeathNameSet.add(srcName);
                killDeathNameSet.add(dstName);

                // 
                GvLogTable logRow = new GvLogTable();

                logRow.setDate(DATE_FORMAT.format(data.getDate()));
                logRow.setSrcCharaName(srcName);
                logRow.setDstCharaName(dstName);
                logRow.setGuildName(order);
                logRow.setPoint(point);
                logRow.setPoint0(point0);
                logRow.setPoint1(point1);

                // 
                logDataQ.add(logRow);

                LOG.info(logRow.toLogFormat());

                pointChecker.check(data.getDate(), logRow);
            }

            return true;
        }

        /* gv?????? */

        Matcher startMatcher = startPattern.matcher(data.getStrData());

        if (startMatcher.matches() && startDate == null) {

            // 0 vs 0?
            GvLogTable log0 = new GvLogTable();

            startDate = data.getDate();
            log0.setDate(DATE_FORMAT.format(startDate));

            String gName0 = RamidoreUtil.encode(startMatcher.group(1), Const.ENCODING);
            String gName1 = RamidoreUtil.encode(startMatcher.group(2), Const.ENCODING);

            log0.setStrictGuildName0(gName0);
            log0.setStrictGuildName1(gName1);

            logDataQ.add(log0);

            LOG.info(DATE_FORMAT.format(startDate) + "\t : " + gName0 + " vs " + gName1);

            return true;
        }

        /* gv?????? */

        Matcher resultMatcher = resultPattern.matcher(data.getStrData());

        if (resultMatcher.find()) {

            String gCode = resultMatcher.group(1);
            String gName = RamidoreUtil.encode(resultMatcher.group(2), Const.ENCODING);
            int winCnt = RamidoreUtil.intValueFromAscHexString(resultMatcher.group(3));
            int loseCnt = RamidoreUtil.intValueFromAscHexString(resultMatcher.group(4));
            int drawCnt = RamidoreUtil.intValueFromAscHexString(resultMatcher.group(5));
            int winPoint = RamidoreUtil.intValueFromDescHexString(resultMatcher.group(6));
            String resultCode = resultMatcher.group(7);

            String result = StringUtils.EMPTY;

            if ("00".equals(resultCode)) {
                result = "?????";
            } else if ("01".equals(resultCode)) {
                result = "????";
            } else if ("02".equals(resultCode)) {
                result = "?????";
            }

            LOG.info(DATE_FORMAT.format(data.getDate()) + "\t : ?[" + gCode + "]??"
                    + gName + "???" + result);
            LOG.info(winCnt + "? " + loseCnt + " " + drawCnt + " ?? " + winPoint);

            // ????????kill/death?????????
            nameSet.removeAll(killDeathNameSet);

            LOG.info("00LA(???????)");
            if (nameSet.isEmpty()) {
                LOG.info("?");
            } else {
                for (String name : nameSet) {

                    LOG.info(name);
                }
            }

            return true;
        }

        return false;
    }

    /**
     * ??.
     */
    private class DuplicateChecker {
        private static final String FORMAT = "%d:%d";
        private Set<String> set = new HashSet<String>();

        public DuplicateChecker() {
            set.add(String.format(FORMAT, 0, 0));
        }

        public boolean check(Date date, int p1, int p2) {
            String val = String.format(FORMAT, p1, p2);
            if (set.contains(val)) {
                LOG.warn(DATE_FORMAT.format(date) + "\t???? : " + p1 + " - " + p2);
                return false;
            } else {
                set.add(val);
                return true;
            }
        }
    }

    ;

    /**
     * ???.
     *
     * @author atmark
     */
    private class PointChecker {

        private int[] p;
        private int[] diff;

        public PointChecker() {
            p = new int[] { 0, 0 };
            diff = new int[] { 0, 0 };
        }

        public void check(Date date, GvLogTable t) {

            this.p[t.getGuildName()] += t.getPoint();

            if (this.p[0] - t.getPoint0() != diff[0]) {
                diff[0] = this.p[0] - t.getPoint0();
                LOG.warn(DATE_FORMAT.format(date) + "\t??? : " + diff[0]);
            } else if (this.p[1] - t.getPoint1() != diff[1]) {
                diff[1] = this.p[1] - t.getPoint1();
                LOG.warn(DATE_FORMAT.format(date) + "\t??? : " + diff[1]);
            }
        }
    }
}