Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package server;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Random;
- import java.util.Timer;
- import java.util.TimerTask;
- import java.util.concurrent.BlockingQueue;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.LinkedBlockingQueue;
- import org.apache.commons.mail.DefaultAuthenticator;
- import org.apache.commons.mail.Email;
- import org.apache.commons.mail.EmailException;
- import org.apache.commons.mail.SimpleEmail;
- import org.jboss.netty.channel.Channel;
- import org.jboss.netty.channel.group.DefaultChannelGroup;
- import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame;
- import org.jboss.netty.util.internal.ConcurrentHashMap;
- import quiz.shared.LoginResponseType;
- import quiz.shared.LoginType;
- import quiz.shared.MessageType;
- import server.SocketEventObject;
- import server.SocketEventType;
- import server.dto.Forgot;
- import server.dto.InRoom;
- import server.dto.IncomingMessageType;
- import server.dto.Login;
- import server.dto.MessageFromUser;
- import server.dto.MessageToUser;
- import server.dto.ResponseLoginMsg;
- import server.dto.Round;
- import server.dto.Top;
- import server.dto.UserNumInRoom;
- import server.dto.WinningMessage;
- import server.entity.Question;
- import server.entity.User;
- import server.game.Room;
- import com.google.gson.Gson;
- import com.google.gson.GsonBuilder;
- public final class ReadQueueHandler {
- static int maxUsersInRoom = 20;
- static int votePersent = 50;
- private final Charset charset = Charset.forName("UTF-8");
- public static final HashMap<Integer, Integer> numOfCharsShowedInAnswer = new HashMap<Integer, Integer>();
- static {
- int v = 0;
- for (int i = 0; i < 31; i++) {
- if (i > 2 && i % 2 != 0)
- v += 1;
- numOfCharsShowedInAnswer.put(i, v);
- }
- }
- // key -> indifierName
- private ConcurrentHashMap<String, Room> rooms;
- private ConcurrentHashMap<String, DefaultChannelGroup> groups;
- // лун -> Channel->getId()
- private ConcurrentHashMap<Integer, User> users;
- public Gson gson;
- private Mng mng;
- // Очередь с вопросами
- private QuestionsQueue questionQueue;
- private final BlockingQueue<SocketEventObject> socketEventObjectQueue;
- private final ExecutorService threadPool;
- private int threadPoolSize;
- private boolean isActive = true;
- public ReadQueueHandler(int threadPoolSize) {
- this.threadPoolSize = threadPoolSize;
- this.threadPool = Executors.newFixedThreadPool(threadPoolSize);
- //
- this.socketEventObjectQueue = new LinkedBlockingQueue<SocketEventObject>();
- this.rooms = new ConcurrentHashMap<String, Room>();
- this.groups = new ConcurrentHashMap<String, DefaultChannelGroup>();
- this.users = new ConcurrentHashMap<Integer, User>();
- this.gson = new Gson();
- this.mng = new Mng();
- // инициализируем очередь(сразу заполнится 100 вопросами)
- this.questionQueue = new QuestionsQueue(this.mng);
- //runRoundTimer();
- }
- private void runMainLogic(){
- SocketEventObject socketEventObject;
- try {
- socketEventObject = socketEventObjectQueue.take();
- System.out.println("TYPE: " + socketEventObject.getType());
- String jsonAsString = (String) socketEventObject
- .getObject();
- System.out.println("MSG: " + jsonAsString);
- System.out.println("socketEventObject.getType(): " + socketEventObject.getType());
- switch (socketEventObject.getType()) {
- case SocketEventType.CONNECTED:
- Channel channel = socketEventObject.getChannel();
- System.out.println("CONNECTED CHANNEL ID: "
- + channel.getId());
- break;
- case SocketEventType.DISCONNEDCED:
- disconnectedProcceed(socketEventObject);
- break;
- case SocketEventType.MESSAGE:
- System.out.println("SocketEventType.MESSAGE:" + (String) socketEventObject.getObject());
- IncomingMessageType msg = gson.fromJson(jsonAsString,
- IncomingMessageType.class);
- switch (msg.getMessageType()) {
- case MessageType.LOGIN:
- System.out.println("LOGIN PROCCEED");
- loginProcceed(socketEventObject);
- break;
- case MessageType.MESSAGE:
- messageProcceed(socketEventObject);
- break;
- case MessageType.VOTE:
- voteProcceed(socketEventObject);
- break;
- case MessageType.TOP:
- topProcceed(socketEventObject);
- break;
- case MessageType.INROOM:
- inRoomProcceed(socketEventObject);
- break;
- case MessageType.FORGOT:
- forgotProcceed(socketEventObject);
- break;
- default:
- break;
- }
- break;
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (EmailException e) {
- e.printStackTrace();
- }
- }
- private void forgotProcceed(SocketEventObject socketEventObject) throws EmailException {
- Forgot forgot = gson.fromJson(
- (String) socketEventObject.getObject(), Forgot.class);
- User user = getuserByEmail(forgot.getEmail());
- if (user != null) {
- String tempBodyMail = new String("Your Username is: " + user.getName() + "\n" + "Your password is: " + user.getPassword()
- + "\n" + "Current experience: " + user.getExp() + "\n \n" + "Trivi Online, Welcome Back");
- String bodyEmail = new String(tempBodyMail.getBytes(charset), charset);
- Email email = new SimpleEmail();
- email.setHostName("smtp.gmail.com");
- email.setCharset("UTF-8");
- email.setSmtpPort(587);
- email.setAuthenticator(new DefaultAuthenticator("noreply@triviapp.net",
- "!qazxsw2"));
- email.setTLS(true);
- email.setFrom("noreply@triviapp.net");
- email.setSubject("Recovery Password - Trivi Online");
- email.setMsg(bodyEmail);
- email.addTo(user.getEmail());
- email.send();
- }
- }
- private void runRoundTimer() {
- Timer timer = new java.util.Timer();
- TimerTask task = new TimerTask() {
- public void run() {
- System.out.println("run timer");
- System.out.println("Rooms: " + rooms.size());
- System.out.println("Users: " + users.size());
- System.out.println("Groups: " + groups.size());
- for(Map.Entry<String, DefaultChannelGroup> entry : groups.entrySet()) {
- System.out.println("Group(" + entry.getKey()+ ") size: " + entry.getValue().size());
- }
- for (Map.Entry<String, Room> entry : rooms.entrySet()) {
- String indifier = entry.getKey();
- Room room = entry.getValue();
- DefaultChannelGroup group = getGroupByIndifierName(indifier);
- if (((System.currentTimeMillis() / 1000) - room.roundStart) > 30
- && group.size() > 0) {
- System.out.println("fireNewRound");
- fireNewRound(room, group,true);
- }
- }
- }
- };
- timer.scheduleAtFixedRate(task, 0, 30000);
- }
- private void inRoomProcceed(SocketEventObject socketEventObject) {
- User user = getUserByChannelId(socketEventObject.getChannel().getId());
- String indifierName = user.getIndifierName();
- DefaultChannelGroup channelGroup = getGroupByIndifierName(indifierName);
- ArrayList<User> users = new ArrayList<User>();
- for (Channel ch : channelGroup) {
- users.add(getUserByChannelId(ch.getId()));
- }
- InRoom inRoom = new InRoom(users);
- sendToUserExplisit(socketEventObject.getChannel(), inRoom, true);
- }
- private void topProcceed(SocketEventObject socketEventObject) {
- DefaultChannelGroup group = getGroupByUserChannelId(socketEventObject
- .getChannel().getId());
- List<User> users = mng.ds.find(User.class).order("-exp").limit(20)
- .asList();
- Top top = new Top(users);
- sendToUserExplisit(socketEventObject.getChannel(), top, true);
- }
- private void fireNewRound(Room room, DefaultChannelGroup group) {
- room.resetVote();
- room.setQuestionWithTime(getQuestion());
- sendToGroup(group, getRoundDTO(room));
- }
- private void fireNewRound(Room room, DefaultChannelGroup group, Boolean lastAnswer) {
- String answer = room.getQuestion().getAnswer();
- room.resetVote();
- room.setQuestionWithTime(getQuestion());
- Round round = getRoundDTO(room);
- round.setLastAnswer(answer);
- sendToGroup(group, round);
- }
- private boolean isVoteFired(int usersInRoom, int usersVotedNum) {
- if (usersInRoom == 0)
- return false;
- if (((usersVotedNum * 100) / usersInRoom) > votePersent)
- return true;
- return false;
- }
- private void voteProcceed(SocketEventObject socketEventObject) {
- Room room = getRoomByUserChannelId(socketEventObject.getChannel()
- .getId());
- DefaultChannelGroup group = getGroupByUserChannelId(socketEventObject
- .getChannel().getId());
- int votesNum = room.incVote();
- if (isVoteFired(group.size(), votesNum)) {
- fireNewRound(room, group,true);
- }
- }
- private User getUserByChannelId(int channelId) {
- return users.get(channelId);
- }
- private Room getRoomByUserChannelId(int channelId) {
- User user = getUserByChannelId(channelId);
- return getRoomByIndifierName(user.getIndifierName());
- }
- private Room getRoomByIndifierName(String indifierName) {
- return rooms.get(indifierName);
- }
- private DefaultChannelGroup getGroupByIndifierName(String indifierName) {
- return groups.get(indifierName);
- }
- private DefaultChannelGroup getGroupByUserChannelId(int channelId) {
- User user = getUserByChannelId(channelId);
- return getGroupByIndifierName(user.getIndifierName());
- }
- private boolean checkForRightAnswer(Room room, String answer) {
- if (room.getQuestion().getAnswer().toLowerCase().trim()
- .equals(answer.toLowerCase().trim())) {
- return true;
- }
- return false;
- }
- private int getExp(Room room, int numOfOpenedChars) {
- int returnExp = (int) Math.round(10 - 0.1 * ((100 / room.getQuestion()
- .getAnswer().length()) * numOfOpenedChars));
- System.out.println("Открытых букв в слове " + numOfOpenedChars);
- System.out.println("Дали экспу " + returnExp);
- return returnExp;
- }
- private void sendToUserExplisit(Channel channel, Object msg, boolean b) {
- Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
- .create();
- sendToUser(channel, gson.toJson(msg), true);
- }
- private void messageProcceed(SocketEventObject socketEventObject) {
- MessageFromUser messageFromUser = gson.fromJson(
- (String) socketEventObject.getObject(), MessageFromUser.class);
- User user = getUserByChannelId(socketEventObject.getChannel().getId());
- Room room = getRoomByIndifierName(user.getIndifierName());
- DefaultChannelGroup group = getGroupByIndifierName(user
- .getIndifierName());
- sendToGroup(
- group,
- new MessageToUser(user.getName(), messageFromUser.getMessage()),
- socketEventObject.getChannel());
- if (checkForRightAnswer(room, messageFromUser.getMessage())) {
- if (room.getLocked().compareAndSet(false, true)) {
- String answer = room.getQuestion().getAnswer();
- fireNewRound(room, group);
- room.getLocked().set(false);
- int exp = getExp(room, messageFromUser.getNumOfChars());
- sendToGroup(group, new WinningMessage(user.getName(), answer, exp));
- getUserByChannelId(socketEventObject.getChannel().getId())
- .addExp(exp);
- }
- }
- }
- private void disconnectedProcceed(SocketEventObject socketEventObject) {
- User user = users.get(socketEventObject.getChannel().getId());
- if (user != null) {
- DefaultChannelGroup channelGroup = getGroupByIndifierName(user
- .getIndifierName());
- channelGroup.remove(socketEventObject.getChannel());
- users.remove(socketEventObject.getChannel().getId());
- mng.ds.save(user);
- }
- }
- private void sendToUser(Channel channel, Object object) {
- sendToUser(channel, gson.toJson(object), true);
- }
- private void sendToUser(Channel channel, String object, boolean b) {
- if (channel.getPipeline().get("wsdecoder") != null) {
- System.out.println("sending to ws");
- channel.write(new TextWebSocketFrame(object));
- } else {
- System.out.println("sending to socket");
- channel.write(object);
- }
- }
- private void sendToGroup(DefaultChannelGroup channelGroup, Object object) {
- for (Channel ch : channelGroup) {
- sendToUser(ch, object);
- }
- }
- private void sendToGroup(DefaultChannelGroup channelGroup, String object,
- boolean b) {
- for (Channel ch : channelGroup) {
- sendToUser(ch, object, b);
- }
- }
- private void sendToGroup(DefaultChannelGroup group,
- MessageToUser messageToUser, Channel channel) {
- for (Channel ch : group) {
- if (!ch.equals(channel))
- sendToUser(ch, messageToUser);
- }
- }
- private void loginProcceed(SocketEventObject socketEventObject) {
- Login login = gson.fromJson((String) socketEventObject.getObject(),
- Login.class);
- User user = getUserByUserName(login.getUsername());
- ResponseLoginMsg responseLoginMsg = getLoginResponse(login,
- (user == null) ? false : true, user);
- sendToUser(socketEventObject.getChannel(), responseLoginMsg);
- System.out.println("loginProcceed before if");
- System.out.println("responseLoginMsg.getType(): " + responseLoginMsg.getType());
- System.out.println("LoginResponseType.OK: " + LoginResponseType.OK);
- if (responseLoginMsg.getType() == LoginResponseType.OK) {
- System.out.println("loginProcceed after if");
- if (user == null) {
- user = new User(login.getUsername(), login.getPassword(),login.getEmail().toLowerCase());
- mng.ds.save(user);
- }
- System.out.println("user must exists!: " + user.getName());
- addNewUser(user, socketEventObject.getChannel());
- Room room = rooms.get(user.getIndifierName());
- Round round = getRoundDTO(room);
- sendToUser(socketEventObject.getChannel(), round);
- }
- }
- private User getUserByUserName(String username) {
- return mng.ds.find(User.class).field("username").containsIgnoreCase(username).get();
- }
- private User getuserByEmail(String email) {
- return mng.ds.find(User.class).field("email").equal(email.toLowerCase()).get();
- }
- private ResponseLoginMsg getLoginResponse(Login login, boolean userExists,
- User user) {
- ResponseLoginMsg response = new ResponseLoginMsg(
- LoginResponseType.USERNOTEXIST);
- if (!login.getUsername().isEmpty()) {
- String username = login.getUsername().toLowerCase();
- String password = login.getPassword().toLowerCase();
- switch (login.getType()) {
- case LoginType.NEWUSER:
- if (userExists == false && getuserByEmail(login.getEmail())==null) {
- response = new ResponseLoginMsg(LoginResponseType.OK);
- } else {
- response = new ResponseLoginMsg(LoginResponseType.USEREXIST);
- }
- break;
- case LoginType.EXISTUSER:
- if (userExists == true && user.getPassword().toLowerCase().equals(password.toLowerCase())) {
- response = new ResponseLoginMsg(LoginResponseType.OK);
- } else {
- response = new ResponseLoginMsg(
- LoginResponseType.USERNOTEXIST);
- }
- break;
- case LoginType.FACEBOOK:
- response = new ResponseLoginMsg(LoginResponseType.OK);
- break;
- }
- }
- return response;
- }
- private void addNewUser(User user, Channel channel) {
- String indifierName = getRoomWithMinGroup();
- if (indifierName == null) {
- indifierName = allocateNewRoom();
- }
- addUserToChannelGroup(indifierName, channel);
- user.setIndifierName(indifierName);
- users.put(channel.getId(), user);
- fireSendUserNumInGroup(indifierName);
- }
- private void fireSendUserNumInGroup(String indifierName) {
- DefaultChannelGroup channelGroup = getGroupByIndifierName(indifierName);
- sendToGroup(channelGroup, new UserNumInRoom(channelGroup.size()));
- }
- private void addUserToChannelGroup(String indifierName, Channel channel) {
- DefaultChannelGroup channelGroup = groups.get(indifierName);
- channelGroup.add(channel);
- }
- // index of room and group
- private String allocateNewRoom() {
- String channelName = createChannelGroup();
- Room room = createRoom();
- rooms.put(channelName, room);
- return channelName;
- }
- private String createChannelGroup() {
- String channelName = (new Long(System.currentTimeMillis())).toString();
- DefaultChannelGroup channelGroup = new DefaultChannelGroup(channelName);
- groups.put(channelName, channelGroup);
- return channelName;
- }
- private String getRoomWithMinGroup() {
- for (DefaultChannelGroup cg : groups.values()) {
- if (cg.size() < maxUsersInRoom) {
- return cg.getName();
- }
- }
- return null;
- }
- private void removeGroup(DefaultChannelGroup channelGroup) {
- groups.remove(channelGroup);
- channelGroup.close();
- }
- private Room createRoom() {
- Room room = new Room();
- room.setQuestion(getQuestion());
- return room;
- }
- private Question getQuestion() {
- // очередь из n вопросов
- // Random random = new Random();
- // Question question = new Question();
- Question question = questionQueue.getNextQuestion();
- System.out.println("QUESTIOn:" + question.getQuestion());
- // question.setQuestion("question_"
- // + new Integer(random.nextInt()).toString());
- // question.setAnswer("answer" + new
- // Integer(random.nextInt()).toString());
- return question;
- }
- public void addEventObject(Channel channel, Object object, int type) {
- System.out.println("addEventObject: " + object.toString());
- socketEventObjectQueue
- .add(new SocketEventObject(channel, object, type));
- runMainLogic();
- }
- private Round getRoundDTO(Room room) {
- Question q = room.getQuestion();
- Round round = new Round();
- round.setAnswer(getAnswerMap(q.getAnswer()));
- round.setQuestion(q.getQuestion() + "( " + q.getAnswer() + ")");
- round.setCharsNum(q.getAnswer().length());
- return round;
- }
- private Map<Integer, String> getAnswerMap(String answer) {
- int answerLength = answer.length();
- int numOfChars = numOfCharsShowedInAnswer.get(answerLength);
- Random random = new Random();
- Map<Integer, String> tmp = new HashMap<Integer, String>();
- int count = 0;
- do {
- int rnd = (random.nextInt(answerLength));
- if (!tmp.containsKey(rnd)) {
- count++;
- tmp.put(rnd, (new Character(answer.charAt(rnd))).toString());
- }
- } while (count < (numOfChars));
- return tmp;
- }
- }
Add Comment
Please, Sign In to add comment