/* * Copyright 2014 The Skfiy Open Association. * * 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.skfiy.typhon.spi.society; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; import org.skfiy.typhon.AbstractComponent; import org.skfiy.typhon.Typhons; import org.skfiy.typhon.domain.GlobalData; import org.skfiy.typhon.domain.Incident; import org.skfiy.typhon.domain.Normal; import org.skfiy.typhon.domain.Player; import org.skfiy.typhon.domain.VacantData; import org.skfiy.typhon.packet.DoubleValue; import org.skfiy.typhon.packet.MultipleValue; import org.skfiy.typhon.packet.Packet; import org.skfiy.typhon.packet.PacketError; import org.skfiy.typhon.packet.SingleValue; import org.skfiy.typhon.packet.SocietyPacket; import org.skfiy.typhon.repository.GlobalDataRepository; import org.skfiy.typhon.repository.IncidentRepository; import org.skfiy.typhon.session.Session; import org.skfiy.typhon.session.SessionContext; import org.skfiy.typhon.session.SessionManager; import org.skfiy.typhon.session.SessionUtils; import org.skfiy.typhon.spi.ConfigurationLoader; import org.skfiy.typhon.spi.IncidentConstants; import org.skfiy.typhon.spi.RoleProvider; import org.skfiy.util.StringUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; /** * * @author Kevin Zou <kevinz@skfiy.org> */ public class SocietyProvider extends AbstractComponent { public static final String CONFIG_SID_SEQ_KEY = "society.lastSid"; private static final AtomicInteger SID_SEQ = new AtomicInteger(1000); private final Timer TIMER = new Timer("Society-Timer", true); private final Timer TIMER1 = new Timer("UpdateSociety-Timer", true); private final List<Society> societies = new ArrayList<>(); private int updateChairmanTime; @Inject private GlobalDataRepository globalDataReposy; @Inject private IncidentRepository incidentReposy; @Inject private SessionManager sessionManager; @Inject private RoleProvider roleProvider; @Inject private ConfigurationLoader configurationLoader; @Override protected void doInit() { GlobalData globalData = globalDataReposy.getGlobalData(GlobalData.Type.society_data); societies.addAll(JSON.parseArray(globalData.getData(), Society.class)); SID_SEQ.set(configurationLoader.getServerInt(CONFIG_SID_SEQ_KEY, 1000)); TIMER.schedule(new TimerTask() { @Override public void run() { // 扫描公会 saveData(); } }, Typhons.getLong("typhon.spi.pvp.saveDataFixedRateMs"), Typhons.getLong("typhon.spi.pvp.saveDataFixedRateMs")); TIMER1.schedule(new TimerTask() { @Override public void run() { updateChairman(); } },120000, Typhons.getLong("typhon.spi.society.updateChairman")); updateChairmanTime = Typhons.getInteger("typhon.spi.society.updateChairman.time"); } @Override protected void doReload() { } @Override protected void doDestroy() { updateChairman(); saveData(); } /** * 创建公会. * * @param packet 协议包 */ public synchronized void create(SocietyPacket packet) { Player player = SessionUtils.getPlayer(); if (StringUtils.isEmpty(packet.getName()) || findByName(packet.getName()) != null) { PacketError error = PacketError.createResult(packet, PacketError.Condition.society_name_illegal); player.getSession().write(error); return; } if (player.getNormal().getSocietyId() > 0) { // 不能接受 PacketError error = PacketError.createResult(packet, PacketError.Condition.not_acceptable); player.getSession().write(error); return; } if (player.getNormal().getSocietyLeaveTime() > System.currentTimeMillis()) { PacketError error = PacketError.createResult(packet, PacketError.Condition.time_over); error.setText("Leave Society time limit"); player.getSession().write(error); return; } int diamond = Typhons.getInteger("typhon.spi.society.create.depletion", 500); SessionUtils.checkDiamond(diamond); // 获取公会的ID int sid; for (;;) { sid = SID_SEQ.getAndIncrement(); if (findBySid(sid) == null) { break; } } // Society society = new Society(); society.setSid(sid); society.setName(packet.getName()); society.setIcon(packet.getIcon()); society.setSummary(packet.getSummary()); society.setChairmanRid(player.getRole().getRid()); // 设置会长权限 Member member = newMember(player); member.setPerm(Member.CHAIRMAN_PERM); society.addMember(member); player.getNormal().setSocietyId(society.getSid()); player.getNormal().setSocietyName(packet.getName()); JSONObject object = new JSONObject(); object.put("place", "CreateSociety"); object.put("societyName", packet.getName()); SessionUtils.decrementDiamond(diamond, object.toString()); societies.add(society); // 设置新的SID号 configurationLoader.setServerProperty(CONFIG_SID_SEQ_KEY, sid); player.getSession().write(Packet.createResult(packet)); roleProvider.updateInformation(); pushRecord(society, member.getName(), null, "create"); } /** * 解散公会. * * @param packet 协议包 */ public void dissolve(Packet packet) { Player player = SessionUtils.getPlayer(); Society society = findBySid(player.getNormal().getSocietyId()); if (society == null || society.findMember(player.getRole().getRid()).getPerm() != Member.CHAIRMAN_PERM) { PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict); player.getSession().write(error); return; } // 删除公会 societies.remove(society); for (Member member : society.getMembers()) { setPlayerSocietyId(member.getRid(), 0); } } /** * * @param packet */ public void loadSocieties(SingleValue packet) { int p = (int) packet.getVal(); MultipleValue result = MultipleValue.createResult(packet); for (int i = (p - 1) * 5; i < (p * 5 + 1); i++) { if (i >= societies.size()) { break; } result.addVal(new SocietyResult(societies.get(i))); } SessionContext.getSession().write(result); } /** * 请受别人入会请求. * * @param packet 协议包 */ public synchronized void accept(SingleValue packet) { Player player = SessionUtils.getPlayer(); Society society = findBySid(player.getNormal().getSocietyId()); if (society.getMembers().size() >= society.getMaxMember()) { PacketError error = PacketError.createResult(packet, PacketError.Condition.size_limit); player.getSession().write(error); return; } int rid = (int) packet.getVal(); Member member = society.findRequestMember(rid); if (getPlayerSocietyId(rid) > 0) { society.removeRequestMember(member); // 不能接受 PacketError error = PacketError.createResult(packet, PacketError.Condition.not_acceptable); player.getSession().write(error); return; } Session beSession = sessionManager.getSession(member.getRid()); if (beSession == null) { VacantData vacantData = roleProvider.loadVacantData(member.getRid()); member.setAvatar(vacantData.getAvatar()); member.setAvatarBorder(vacantData.getAvatarBorder()); member.setLevel(vacantData.getLevel()); member.setName(vacantData.getName()); } else { Player bePlayer = SessionUtils.getPlayer(beSession); Normal beNormal = bePlayer.getNormal(); member.setAvatar(beNormal.getAvatar()); member.setAvatarBorder(beNormal.getAvatarBorder()); member.setLevel(beNormal.getLevel()); member.setName(bePlayer.getRole().getName()); } society.addMember(member); society.removeRequestMember(member); // 设置玩家的公会ID setPlayerSocietyId(rid, society.getSid()); // 排序公会.. sortSocieties(); pushRecord(society, member.getName(), null, "join"); } /** * 拒绝别人的申请. * * @param packet 协议包 */ public void reject(SingleValue packet) { Player player = SessionUtils.getPlayer(); Society society = findBySid(player.getNormal().getSocietyId()); int rid = (int) packet.getVal(); Member member = society.findRequestMember(rid); society.removeRequestMember(member); } /** * 申请加入公会. * * @param packet 协议包 */ public void apply(SingleValue packet) { Player player = SessionUtils.getPlayer(); int sid = (int) packet.getVal(); Society society = findBySid(sid); if (society == null) { PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict); player.getSession().write(error); return; } if (society.getMembers().size() >= society.getMaxMember()) { PacketError error = PacketError.createResult(packet, PacketError.Condition.size_limit); player.getSession().write(error); return; } if (society.findMember(player.getRole().getRid()) != null || society.findRequestMember(player.getRole().getRid()) != null) { return; } if (player.getNormal().getSocietyLeaveTime() > System.currentTimeMillis()) { PacketError error = PacketError.createResult(packet, PacketError.Condition.time_over); error.setText("Leave Society time limit"); player.getSession().write(error); return; } Member member = newMember(player); society.addRequestMember(member); // FIXME 给公会发一条消息 // 排序公会 sortSocieties(); } /** * 踢出某个成员出公会. * * @param packet */ public void kickout(SingleValue packet) { Player player = SessionUtils.getPlayer(); int rid = (int) packet.getVal(); if (rid == player.getRole().getRid()) { // 无法把自己踢出公会 return; } Society society = findBySid(player.getNormal().getSocietyId()); Member member = society.findMember(rid); if (member != null) { setPlayerSocietyId(member.getRid(), 0); society.removeMember(member); // 排序公会 sortSocieties(); } pushRecord(society, member.getName(), player.getRole().getName(), "kickout"); } /** * 离开公会. * * @param packet 协议包 */ public void leave(Packet packet) { Player player = SessionUtils.getPlayer(); Society society = findBySid(player.getNormal().getSocietyId()); Member member = society.findMember(player.getRole().getRid()); if (member.getPerm() == Member.CHAIRMAN_PERM) { PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict); error.setText("is chairman"); player.getSession().write(error); return; } setPlayerSocietyId(member.getRid(), 0); society.removeMember(member); player.getSession().write(Packet.createResult(packet)); // 排序公会 sortSocieties(); // 离开工会 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.HOUR, 24); player.getNormal().setSocietyLeaveTime(calendar.getTimeInMillis()); pushRecord(society, member.getName(), null, "leave"); } /** * 加载当前公会信息. * * @param packet 协议包 */ public void load(Packet packet) { Player player = SessionUtils.getPlayer(); SingleValue result = SingleValue.createResult(packet, findBySid(player.getNormal().getSocietyId())); player.getSession().write(result); } /** * 修改信息 * * @param packet 协议包 */ public void updateInfo(DoubleValue packet) { Player player = SessionUtils.getPlayer(); Society society = findBySid(player.getNormal().getSocietyId()); String flag = (String) packet.getFirst(); String v = (String) packet.getSecond(); Member member = society.findMember(player.getRole().getRid()); if (member.getPerm() == Member.NORMAL_PERM) { PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict); error.setText("No prem"); player.getSession().write(error); return; } switch (flag) { case "summary": society.setSummary(v); break; case "icon": society.setIcon(v); break; case "levelLimit": society.setLevelLimit(Integer.valueOf(v)); break; } player.getSession().write(Packet.createResult(packet)); } /** * 设置公会权限. * * @param packet 协议包 */ public void updatePerm(DoubleValue packet) { Player player = SessionUtils.getPlayer(); Society society = findBySid(player.getNormal().getSocietyId()); int rid = (int) packet.getFirst(); int p = (int) packet.getSecond(); Member member = society.findMember(rid); if (member.getRid() == player.getRole().getRid()) { PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict); error.setText("myself"); player.getSession().write(error); return; } Member myMember = society.findMember(player.getRole().getRid()); if (myMember.getPerm() != Member.CHAIRMAN_PERM) { PacketError error = PacketError.createResult(packet, PacketError.Condition.conflict); error.setText("Need chairman perm."); player.getSession().write(error); return; } updatePerm(society, myMember, member, p); player.getSession().write(Packet.createResult(packet)); } /** * 根据公会ID查询公会对象. * * @param sid 公会ID * @return */ public Society findBySid(int sid) { for (Society soc : societies) { if (soc.getSid() == sid) { return soc; } } return null; } /** * 根据公会名称查询公会对象. * * @param name 公会名称 * @return */ public Society findByName(String name) { for (Society soc : societies) { if (soc.getName().equals(name)) { return soc; } } return null; } /** * 会长三天未上线更换会长 * * @param member * @param p */ public void updateChairman() { for (Society soc : societies) { for (Member member : soc.getMembers()) { if (member.getPerm() == Member.CHAIRMAN_PERM) { Session session = sessionManager.getSession(member.getRid()); if (session != null) { break; } else { VacantData vacantData = roleProvider.loadVacantData(member.getRid()); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(vacantData.getLastLogoutTime()); roleProvider.clearCalendar(calendar); calendar.add(Calendar.DATE, updateChairmanTime); if (System.currentTimeMillis() < calendar.getTimeInMillis()) { break; } else { member.setPerm(Member.NORMAL_PERM); Member member1 = getMember(soc); member1.setPerm(Member.CHAIRMAN_PERM); soc.setChairmanRid(member1.getRid()); break; } } } } } } private Member getMember(Society society) { List<Member> members = new ArrayList<>(); for (Member member : society.getMembers()) { if (member.getPerm() == Member.ELDER_PERM) { Session session = sessionManager.getSession(member.getRid()); if (session != null) { return member; } else { members.add(member); } } } if (members.isEmpty()) { for (Member member : society.getMembers()) { if (member.getPerm() == Member.NORMAL_PERM) { Session session = sessionManager.getSession(member.getRid()); if (session != null) { return member; } else { members.add(member); } } } } Member meb = members.get(0); VacantData vacantData = roleProvider.loadVacantData(meb.getRid()); for (int i = 0; i < members.size(); i++) { VacantData nextVacantData = roleProvider.loadVacantData(members.get(i).getRid()); if (nextVacantData.getLastLogoutTime() > vacantData.getLastLogoutTime()) { meb = members.get(i); vacantData = nextVacantData; } } return meb; } private void updatePerm(Society society, Member myMember, Member member, int p) { if (p == Member.CHAIRMAN_PERM) { // 设置会长<转让公会> member.setPerm(Member.CHAIRMAN_PERM); society.setChairmanRid(member.getRid()); myMember.setPerm(Member.NORMAL_PERM); pushRecord(society, member.getName(), myMember.getName(), "perm_1"); } else if (p == Member.ELDER_PERM) { // 设置长老 member.setPerm(Member.ELDER_PERM); pushRecord(society, member.getName(), myMember.getName(), "perm_2"); } else { member.setPerm(Member.NORMAL_PERM); pushRecord(society, member.getName(), myMember.getName(), "perm_0"); } } private void pushRecord(Society society, String name, String annex, String event) { Record record = new Record(); record.setTime(System.currentTimeMillis() / 1000); record.setName(name); record.setAnnex(annex); record.setEvent(event); society.getRecords().add(record); } private synchronized void sortSocieties() { Collections.sort(societies); } private int getPlayerSocietyId(int rid) { Session session = sessionManager.getSession(rid); if (session == null) { return roleProvider.loadVacantData(rid).getSocietyId(); } Player player = SessionUtils.getPlayer(session); return player.getNormal().getSocietyId(); } private void setPlayerSocietyId(int rid, int societyId) { Session session = sessionManager.getSession(rid); if (session != null) { Player player = SessionUtils.getPlayer(session); player.getNormal().setSocietyId(societyId); if (societyId == 0) { player.getNormal().setSocietyName(null); } else { player.getNormal().setSocietyName(findBySid(societyId).getName()); } roleProvider.updateInformation(); } else { // 设置玩家的公会ID VacantData vacantData = roleProvider.loadVacantData(rid); vacantData.setSocietyId(societyId); Incident incident = new Incident(); incident.setUid(rid); incident.setData(String.valueOf(societyId)); incident.setEventName(IncidentConstants.EVENT_SOCIETY_SET_PLAYER_SOCIETY_ID); incidentReposy.save(incident); } } private Member newMember(Player player) { Member member = new Member(); member.setRid(player.getRole().getRid()); member.setName(player.getRole().getName()); member.setAvatar(player.getNormal().getAvatar()); member.setAvatarBorder(player.getNormal().getAvatarBorder()); member.setLevel(player.getNormal().getLevel()); return member; } private void saveData() { GlobalData globalData = new GlobalData(); globalData.setType(GlobalData.Type.society_data); globalData.setData(JSON.toJSONString(societies)); globalDataReposy.updateGlobalData(globalData); } }