1 package org.hedgewars.hedgeroid.netplay; |
1 package org.hedgewars.hedgeroid.netplay; |
2 |
2 |
3 import java.io.File; |
3 import java.io.File; |
4 import java.io.FileNotFoundException; |
4 import java.io.FileNotFoundException; |
|
5 import java.util.Map; |
|
6 import java.util.TreeMap; |
5 |
7 |
6 import org.hedgewars.hedgeroid.R; |
8 import org.hedgewars.hedgeroid.R; |
7 import org.hedgewars.hedgeroid.Utils; |
9 import org.hedgewars.hedgeroid.Utils; |
8 import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom; |
10 import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom; |
|
11 import org.hedgewars.hedgeroid.Datastructures.Team; |
9 import org.hedgewars.hedgeroid.Datastructures.TeamInGame; |
12 import org.hedgewars.hedgeroid.Datastructures.TeamInGame; |
10 import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; |
13 import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; |
11 import org.hedgewars.hedgeroid.frontlib.Flib; |
14 import org.hedgewars.hedgeroid.frontlib.Flib; |
12 import org.hedgewars.hedgeroid.frontlib.Frontlib; |
15 import org.hedgewars.hedgeroid.frontlib.Frontlib; |
13 import org.hedgewars.hedgeroid.frontlib.Frontlib.BoolCallback; |
16 import org.hedgewars.hedgeroid.frontlib.Frontlib.BoolCallback; |
80 public final RoomPlayerlist roomPlayerlist = new RoomPlayerlist(); |
83 public final RoomPlayerlist roomPlayerlist = new RoomPlayerlist(); |
81 public final Roomlist roomList = new Roomlist(); |
84 public final Roomlist roomList = new Roomlist(); |
82 public final MessageLog lobbyChatlog; |
85 public final MessageLog lobbyChatlog; |
83 public final MessageLog roomChatlog; |
86 public final MessageLog roomChatlog; |
84 public final Teamlist roomTeamlist = new Teamlist(); |
87 public final Teamlist roomTeamlist = new Teamlist(); |
|
88 private final Map<String, Team> roomRequestedTeams = new TreeMap<String, Team>(); |
85 |
89 |
86 public Netplay(Context appContext) { |
90 public Netplay(Context appContext) { |
87 this.appContext = appContext; |
91 this.appContext = appContext; |
88 broadcastManager = LocalBroadcastManager.getInstance(appContext); |
92 broadcastManager = LocalBroadcastManager.getInstance(appContext); |
89 lobbyChatlog = new MessageLog(appContext); |
93 lobbyChatlog = new MessageLog(appContext); |
131 public void sendFollowPlayer(String nick) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_FOLLOW_PLAYER, nick); } |
135 public void sendFollowPlayer(String nick) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_FOLLOW_PLAYER, nick); } |
132 public void sendJoinRoom(String name) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_JOIN_ROOM, name); } |
136 public void sendJoinRoom(String name) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_JOIN_ROOM, name); } |
133 public void sendCreateRoom(String name) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_CREATE_ROOM, name); } |
137 public void sendCreateRoom(String name) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_CREATE_ROOM, name); } |
134 public void sendLeaveRoom(String message) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_LEAVE_ROOM, message); } |
138 public void sendLeaveRoom(String message) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_LEAVE_ROOM, message); } |
135 public void sendKick(String player) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_KICK, player); } |
139 public void sendKick(String player) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_KICK, player); } |
|
140 public void sendAddTeam(Team newTeam) { |
|
141 roomRequestedTeams.put(newTeam.name, newTeam); |
|
142 sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_ADD_TEAM, newTeam); |
|
143 } |
|
144 public void sendRemoveTeam(String teamName) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_REMOVE_TEAM, teamName); } |
|
145 public void sendTeamColorIndex(String teamName, int colorIndex) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_TEAM_COLOR_INDEX, colorIndex, teamName); } |
|
146 public void sendTeamHogCount(String teamName, int hogCount) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_TEAM_HOG_COUNT, hogCount, teamName); } |
136 |
147 |
137 public void disconnect() { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_DISCONNECT, "User Quit"); } |
148 public void disconnect() { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_DISCONNECT, "User Quit"); } |
138 |
149 |
139 private static Netplay instance; |
150 private static Netplay instance; |
140 |
151 |
200 connection.setFastTickRate(false); |
211 connection.setFastTickRate(false); |
201 } |
212 } |
202 } |
213 } |
203 |
214 |
204 private boolean sendToNet(int what) { |
215 private boolean sendToNet(int what) { |
|
216 return sendToNet(what, 0, null); |
|
217 } |
|
218 |
|
219 private boolean sendToNet(int what, Object obj) { |
|
220 return sendToNet(what, 0, obj); |
|
221 } |
|
222 |
|
223 private boolean sendToNet(int what, int arg1, Object obj) { |
205 if(connection != null) { |
224 if(connection != null) { |
206 Handler handler = connection.toNetHandler; |
225 Handler handler = connection.toNetHandler; |
207 return handler.sendMessage(handler.obtainMessage(what)); |
226 return handler.sendMessage(handler.obtainMessage(what, arg1, 0, obj)); |
208 } else { |
|
209 return false; |
|
210 } |
|
211 } |
|
212 |
|
213 private boolean sendToNet(int what, Object obj) { |
|
214 if(connection != null) { |
|
215 Handler handler = connection.toNetHandler; |
|
216 return handler.sendMessage(handler.obtainMessage(what, obj)); |
|
217 } else { |
227 } else { |
218 return false; |
228 return false; |
219 } |
229 } |
220 } |
230 } |
221 |
231 |
336 } |
346 } |
337 case MSG_ENTER_ROOM_FROM_LOBBY: { |
347 case MSG_ENTER_ROOM_FROM_LOBBY: { |
338 roomChatlog.clear(); |
348 roomChatlog.clear(); |
339 roomPlayerlist.clear(); |
349 roomPlayerlist.clear(); |
340 roomTeamlist.clear(); |
350 roomTeamlist.clear(); |
|
351 roomRequestedTeams.clear(); |
341 changeState(State.ROOM); |
352 changeState(State.ROOM); |
342 chief = (Boolean)msg.obj; |
353 chief = (Boolean)msg.obj; |
343 Intent intent = new Intent(ACTION_ENTERED_ROOM_FROM_LOBBY); |
354 Intent intent = new Intent(ACTION_ENTERED_ROOM_FROM_LOBBY); |
344 broadcastManager.sendBroadcastSync(intent); |
355 broadcastManager.sendBroadcastSync(intent); |
345 break; |
356 break; |
356 Pair<String, Boolean> args = (Pair<String, Boolean>)msg.obj; |
367 Pair<String, Boolean> args = (Pair<String, Boolean>)msg.obj; |
357 roomPlayerlist.setReady(args.first, args.second); |
368 roomPlayerlist.setReady(args.first, args.second); |
358 break; |
369 break; |
359 } |
370 } |
360 case MSG_TEAM_ADDED: { |
371 case MSG_TEAM_ADDED: { |
361 roomTeamlist.addTeamWithNewId((TeamInGame)msg.obj); |
372 Team newTeam = (Team)msg.obj; |
|
373 TeamIngameAttributes attrs = new TeamIngameAttributes(playerName, roomTeamlist.getUnusedOrRandomColorIndex(), TeamIngameAttributes.DEFAULT_HOG_COUNT, false); |
|
374 TeamInGame tig = new TeamInGame(newTeam, attrs); |
|
375 roomTeamlist.addTeamWithNewId(tig); |
|
376 if(chief) { |
|
377 sendTeamColorIndex(newTeam.name, attrs.colorIndex); |
|
378 sendTeamHogCount(newTeam.name, attrs.hogCount); |
|
379 } |
362 break; |
380 break; |
363 } |
381 } |
364 case MSG_TEAM_DELETED: { |
382 case MSG_TEAM_DELETED: { |
365 roomTeamlist.remove((String)msg.obj); |
383 roomTeamlist.remove((String)msg.obj); |
366 break; |
384 break; |
367 } |
385 } |
368 case MSG_TEAM_ACCEPTED: { |
386 case MSG_TEAM_ACCEPTED: { |
369 // TODO depends: adding teams |
387 Team requestedTeam = roomRequestedTeams.remove(msg.obj); |
|
388 if(requestedTeam!=null) { |
|
389 TeamIngameAttributes attrs = new TeamIngameAttributes(playerName, roomTeamlist.getUnusedOrRandomColorIndex(), TeamIngameAttributes.DEFAULT_HOG_COUNT, false); |
|
390 TeamInGame tig = new TeamInGame(requestedTeam, attrs); |
|
391 roomTeamlist.addTeamWithNewId(tig); |
|
392 if(chief) { |
|
393 sendTeamColorIndex(requestedTeam.name, attrs.colorIndex); |
|
394 sendTeamHogCount(requestedTeam.name, attrs.hogCount); |
|
395 } |
|
396 } else { |
|
397 Log.e("Netplay", "Got accepted message for team that was never requested."); |
|
398 } |
370 break; |
399 break; |
371 } |
400 } |
372 case MSG_TEAM_COLOR_CHANGED: { |
401 case MSG_TEAM_COLOR_CHANGED: { |
373 Pair<TeamInGame, Long> oldEntry = roomTeamlist.get((String)msg.obj); |
402 Pair<TeamInGame, Long> oldEntry = roomTeamlist.get((String)msg.obj); |
374 if(oldEntry != null) { |
403 if(oldEntry != null) { |
410 public final ToNetHandler toNetHandler; |
439 public final ToNetHandler toNetHandler; |
411 |
440 |
412 private final Context appContext; |
441 private final Context appContext; |
413 private final FromNetHandler fromNetHandler; |
442 private final FromNetHandler fromNetHandler; |
414 private final TickHandler tickHandler; |
443 private final TickHandler tickHandler; |
415 |
444 |
416 /** |
445 /** |
417 * conn can only be null while connecting (the first thing in the thread), and directly after disconnecting, |
446 * conn can only be null while connecting (the first thing in the thread), and directly after disconnecting, |
418 * in the same message (the looper is shut down on disconnect, so there will be no messages after that). |
447 * in the same message (the looper is shut down on disconnect, so there will be no messages after that). |
419 */ |
448 */ |
420 private NetconnPtr conn; |
449 private NetconnPtr conn; |
587 } |
616 } |
588 }; |
617 }; |
589 |
618 |
590 private final TeamCallback teamAddedCb = new TeamCallback() { |
619 private final TeamCallback teamAddedCb = new TeamCallback() { |
591 public void callback(Pointer context, TeamPtr team) { |
620 public void callback(Pointer context, TeamPtr team) { |
592 sendFromNet(FromNetHandler.MSG_TEAM_ADDED, team.deref()); |
621 sendFromNet(FromNetHandler.MSG_TEAM_ADDED, team.deref().team); |
593 } |
622 } |
594 }; |
623 }; |
595 |
624 |
596 private final StrCallback teamDeletedCb = new StrCallback() { |
625 private final StrCallback teamDeletedCb = new StrCallback() { |
597 public void callback(Pointer context, String teamName) { |
626 public void callback(Pointer context, String teamName) { |
672 public static final int MSG_SEND_FOLLOW_PLAYER = 6; |
701 public static final int MSG_SEND_FOLLOW_PLAYER = 6; |
673 public static final int MSG_SEND_JOIN_ROOM = 7; |
702 public static final int MSG_SEND_JOIN_ROOM = 7; |
674 public static final int MSG_SEND_CREATE_ROOM = 8; |
703 public static final int MSG_SEND_CREATE_ROOM = 8; |
675 public static final int MSG_SEND_LEAVE_ROOM = 9; |
704 public static final int MSG_SEND_LEAVE_ROOM = 9; |
676 public static final int MSG_SEND_KICK = 10; |
705 public static final int MSG_SEND_KICK = 10; |
677 |
706 public static final int MSG_SEND_ADD_TEAM = 11; |
678 public static final int MSG_DISCONNECT = 11; |
707 public static final int MSG_SEND_REMOVE_TEAM = 12; |
|
708 public static final int MSG_DISCONNECT = 13; |
|
709 public static final int MSG_SEND_TEAM_COLOR_INDEX = 14; |
|
710 public static final int MSG_SEND_TEAM_HOG_COUNT = 15; |
679 |
711 |
680 public ToNetHandler(Looper looper) { |
712 public ToNetHandler(Looper looper) { |
681 super(looper); |
713 super(looper); |
682 } |
714 } |
683 |
715 |
695 case MSG_SEND_QUIT: { |
727 case MSG_SEND_QUIT: { |
696 FLIB.flib_netconn_send_quit(conn, (String)msg.obj); |
728 FLIB.flib_netconn_send_quit(conn, (String)msg.obj); |
697 break; |
729 break; |
698 } |
730 } |
699 case MSG_SEND_ROOMLIST_REQUEST: { |
731 case MSG_SEND_ROOMLIST_REQUEST: { |
700 FLIB.flib_netconn_send_request_roomlist(conn); // TODO restrict to lobby state? |
732 FLIB.flib_netconn_send_request_roomlist(conn); |
701 break; |
733 break; |
702 } |
734 } |
703 case MSG_SEND_PLAYER_INFO_REQUEST: { |
735 case MSG_SEND_PLAYER_INFO_REQUEST: { |
704 FLIB.flib_netconn_send_playerInfo(conn, (String)msg.obj); |
736 FLIB.flib_netconn_send_playerInfo(conn, (String)msg.obj); |
705 break; |
737 break; |
730 } |
762 } |
731 case MSG_SEND_KICK: { |
763 case MSG_SEND_KICK: { |
732 FLIB.flib_netconn_send_kick(conn, (String)msg.obj); |
764 FLIB.flib_netconn_send_kick(conn, (String)msg.obj); |
733 break; |
765 break; |
734 } |
766 } |
|
767 case MSG_SEND_ADD_TEAM: { |
|
768 FLIB.flib_netconn_send_addTeam(conn, TeamPtr.createJavaOwned((Team)msg.obj)); |
|
769 break; |
|
770 } |
|
771 case MSG_SEND_REMOVE_TEAM: { |
|
772 if(FLIB.flib_netconn_send_removeTeam(conn, (String)msg.obj)==0) { |
|
773 sendFromNet(FromNetHandler.MSG_TEAM_DELETED, msg.obj); |
|
774 } |
|
775 break; |
|
776 } |
735 case MSG_DISCONNECT: { |
777 case MSG_DISCONNECT: { |
736 FLIB.flib_netconn_send_quit(conn, (String)msg.obj); |
778 FLIB.flib_netconn_send_quit(conn, (String)msg.obj); |
737 shutdown(false, "User quit"); |
779 shutdown(false, "User quit"); |
738 break; |
780 break; |
739 } |
781 } |
|
782 case MSG_SEND_TEAM_COLOR_INDEX: { |
|
783 if(FLIB.flib_netconn_send_teamColor(conn, (String)msg.obj, msg.arg1)==0) { |
|
784 sendFromNet(FromNetHandler.MSG_TEAM_COLOR_CHANGED, msg.arg1, msg.obj); |
|
785 } |
|
786 break; |
|
787 } |
|
788 case MSG_SEND_TEAM_HOG_COUNT: { |
|
789 if(FLIB.flib_netconn_send_teamHogCount(conn, (String)msg.obj, msg.arg1)==0) { |
|
790 sendFromNet(FromNetHandler.MSG_HOG_COUNT_CHANGED, msg.arg1, msg.obj); |
|
791 } |
|
792 break; |
|
793 } |
740 default: { |
794 default: { |
741 Log.e("ToNetHandler", "Unknown message type: "+msg.what); |
795 Log.e("ToNetHandler", "Unknown message type: "+msg.what); |
742 break; |
796 break; |
743 } |
797 } |
744 } |
798 } |