# HG changeset patch # User Medo # Date 1344285576 -7200 # Node ID 2fb781bbdd5114790abd478dffb8b2985dd58e2d # Parent 45b9f25ff611b698fd5092a37dcc0c29613852a8 Hedgeroid: Start using the frontlib for more operations diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/assets/assetsversion.txt --- a/project_files/Android-build/SDL-android-project/assets/assetsversion.txt Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/assets/assetsversion.txt Mon Aug 06 22:39:36 2012 +0200 @@ -1,1 +1,1 @@ -1 \ No newline at end of file +4 \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/libs/ini4j-0.5.2.jar Binary file project_files/Android-build/SDL-android-project/libs/ini4j-0.5.2.jar has changed diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_off.png Binary file project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_off.png has changed diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_on.png Binary file project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_on.png has changed diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/layout-large/activity_lobby.xml --- a/project_files/Android-build/SDL-android-project/res/layout-large/activity_lobby.xml Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/res/layout-large/activity_lobby.xml Mon Aug 06 22:39:36 2012 +0200 @@ -45,8 +45,8 @@ android:id="@+id/playerListFragment" android:layout_width="fill_parent" android:layout_height="fill_parent" - class="org.hedgewars.hedgeroid.netplay.PlayerlistFragment" - tools:layout="@layout/lobby_players_fragment" /> + class="org.hedgewars.hedgeroid.netplay.LobbyPlayerlistFragment" + tools:layout="@layout/fragment_playerlist" /> + class="org.hedgewars.hedgeroid.netplay.LobbyPlayerlistFragment" + tools:layout="@layout/fragment_playerlist" /> diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/layout/activity_netroom.xml --- a/project_files/Android-build/SDL-android-project/res/layout/activity_netroom.xml Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/res/layout/activity_netroom.xml Mon Aug 06 22:39:36 2012 +0200 @@ -26,14 +26,18 @@ android:id="@+id/mapFrame" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_marginRight="10dp" android:layout_weight="1" - android:layout_marginRight="10dp" android:background="@drawable/box" > - + tools:layout="@layout/fragment_map" /> + --> - + tools:layout="@layout/fragment_settings" /> + --> - - + android:layout_width="fill_parent" + android:layout_height="fill_parent" + class="org.hedgewars.hedgeroid.netplay.TeamlistFragment" + tools:layout="@layout/fragment_teamlist" /> @@ -74,12 +83,12 @@ android:layout_below="@id/upperFrame" android:background="@drawable/box" > - + class="org.hedgewars.hedgeroid.netplay.RoomPlayerlistFragment" + tools:layout="@layout/fragment_playerlist" /> + + + + + + \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/layout/fragment_teamlist.xml --- a/project_files/Android-build/SDL-android-project/res/layout/fragment_teamlist.xml Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_teamlist.xml Mon Aug 06 22:39:36 2012 +0200 @@ -6,7 +6,7 @@ android:orientation="vertical" > - - - - - - \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/menu/room_playerlist_chief_context.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_chief_context.xml Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/menu/room_playerlist_context.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_context.xml Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/basicsettings.ini --- a/project_files/Android-build/SDL-android-project/res/raw/basicsettings.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -[DamagePercent] -checkOverMax=false -times1000=false -command=e$damagepct -default=100 -image=Damage -max=300 -min=10 -title=Damage Modifier - -[TurnTime] -checkOverMax=true -times1000=true -command=e$turntime -default=45 -image=Time -max=100 -min=1 -title=Turn Time - -[InitialHealth] -checkOverMax=false -times1000=false -command=inithealth -default=200 -image=Health -max=200 -min=50 -title=Initial Health - -[SuddenDeathTimeout] -checkOverMax=true -times1000=false -command=e$sd_turns -default=15 -image=SuddenDeath -max=50 -min=0 -title=Sudden Death Timeout - -[CrateDropTurns] -checkOverMax=false -times1000=false -command=e$casefreq -default=5 -image=Box -max=9 -min=0 -title=Crate Drop Turns - -[MinesTime] -checkOverMax=false -times1000=true -command=e$minestime -default=3 -image=Time -max=5 -min=-1 -title=Mines Time - -[MinesNumber] -checkOverMax=false -times1000=false -command=e$minesnum -default=4 -image=Mine -max=80 -min=0 -title=Mines Number - -[MinesDudPercent] -checkOverMax=false -times1000=false -command=e$minedudpct -default=0 -image=Dud -max=100 -min=0 -title=Dud Mines Probability (%) - -[Explosives] -checkOverMax=false -times1000=false -command=e$explosives -default=2 -image=Damage -max=40 -min=0 -title=Explosives - -[HealthCratePercent] -checkOverMax=false -times1000=false -command=e$healthprob -default=35 -image=Health -max=100 -min=0 -title=Health Kit Probability (%) - -[HealthCrateHP] -checkOverMax=false -times1000=false -command=e$hcaseamount -default=25 -image=Health -max=200 -min=0 -title=Health Amount in Kit - -[SuddenDeathWaterRise] -checkOverMax=false -times1000=false -command=e$waterrise -default=47 -image=SuddenDeath -max=100 -min=0 -title=Water Rise Amount - -[SuddenDeathHealthDecrease] -checkOverMax=false -times1000=false -command=e$healthdec -default=5 -image=SuddenDeath -max=100 -min=0 -title=Health Decrease - -[RopeLengthPercent] -checkOverMax=false -times1000=false -command=e$ropepct -default=100 -image=Rope -max=999 -min=25 -title=Rope Length (%) - -[GetAwayTimePercent] -checkOverMax=false -times1000=false -command=e$getawaytime -default=100 -image=Time -max=999 -min=0 -title=Get Away Time (%) - diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/gamemods.ini --- a/project_files/Android-build/SDL-android-project/res/raw/gamemods.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -[SolidLand] -bitmaskIndex=2 - -[Border] -bitmaskIndex=3 - -[DivideTeams] -bitmaskIndex=4 - -[LowGravity] -bitmaskIndex=5 - -[LaserSight] -bitmaskIndex=6 - -[Invulnerable] -bitmaskIndex=7 - -[ResetHealth] -bitmaskIndex=8 - -[Vampiric] -bitmaskIndex=9 - -[Karma] -bitmaskIndex=10 - -[Artillery] -bitmaskIndex=11 - -[Forts] -bitmaskIndex=12 - -[RandomOrder] -bitmaskIndex=13 - -[King] -bitmaskIndex=14 - -[PlaceHog] -bitmaskIndex=15 - -[SharedAmmo] -bitmaskIndex=16 - -[DisableGirders] -bitmaskIndex=17 - -[DisableLandObjects] -bitmaskIndex=18 - -[AISurvival] -bitmaskIndex=19 - -[InfAttack] -bitmaskIndex=20 - -[ResetWeps] -bitmaskIndex=21 - -[PerHogAmmo] -bitmaskIndex=22 - -[DisableWind] -bitmaskIndex=23 - -[MoreWind] -bitmaskIndex=24 - -[TagTeam] -bitmaskIndex=25 - -[BottomBorder] -bitmaskIndex=26 diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_barrelmayhem.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_barrelmayhem.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Barrel Mayhem - -[BasicSettings] -DamagePercent=100 -TurnTime=30 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=0 -MinesTime=0 -MinesNumber=0 -MinesDudPercent=0 -Explosives=80 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=true -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_cleanslate.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_cleanslate.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Clean Slate - -[BasicSettings] -DamagePercent=100 -TurnTime=45 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=5 -MinesTime=3 -MinesNumber=4 -MinesDudPercent=0 -Explosives=2 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=true -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=false -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=true -ResetWeps=true -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_default_scheme.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_default_scheme.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Default - -[BasicSettings] -DamagePercent=100 -TurnTime=45 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=5 -MinesTime=3 -MinesNumber=4 -MinesDudPercent=0 -Explosives=2 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=false -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_fortmode.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_fortmode.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Fort Mode - -[BasicSettings] -DamagePercent=100 -TurnTime=45 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=5 -MinesTime=3 -MinesNumber=0 -MinesDudPercent=0 -Explosives=0 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=true -LowGravity=true -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=true -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=false -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_kingmode.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_kingmode.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=King Mode - -[BasicSettings] -DamagePercent=100 -TurnTime=45 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=5 -MinesTime=3 -MinesNumber=4 -MinesDudPercent=0 -Explosives=2 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=true -PlaceHog=false -SharedAmmo=false -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_minefield.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_minefield.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Minefield - -[BasicSettings] -DamagePercent=100 -TurnTime=30 -InitialHealth=50 -SuddenDeathTimeout=15 -CrateDropTurns=0 -MinesTime=0 -MinesNumber=80 -MinesDudPercent=0 -Explosives=0 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=true -DisableGirders=true -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_promode.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_promode.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Pro Mode - -[BasicSettings] -DamagePercent=100 -TurnTime=15 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=0 -MinesTime=3 -MinesNumber=0 -MinesDudPercent=0 -Explosives=2 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=true -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_shoppa.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_shoppa.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Shoppa - -[BasicSettings] -DamagePercent=100 -TurnTime=30 -InitialHealth=100 -SuddenDeathTimeout=50 -CrateDropTurns=1 -MinesTime=3 -MinesNumber=0 -MinesDudPercent=0 -Explosives=0 -HealthCratePercent=0 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=true -DivideTeams=true -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=true -DisableGirders=true -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_thinkingwithportals.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_thinkingwithportals.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Thinking with Portals - -[BasicSettings] -DamagePercent=100 -TurnTime=45 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=2 -MinesTime=3 -MinesNumber=5 -MinesDudPercent=0 -Explosives=5 -HealthCratePercent=25 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=true -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=false -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_timeless.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_timeless.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Timeless - -[BasicSettings] -DamagePercent=100 -TurnTime=9999 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=5 -MinesTime=3 -MinesNumber=5 -MinesDudPercent=10 -Explosives=2 -HealthCratePercent=35 -HealthCrateHP=30 -SuddenDeathWaterRise=0 -SuddenDeathHealthDecrease=0 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=false -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=true -DisableGirders=false -DisableLandObjects=false -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=true -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/scheme_tunnelhogs.ini --- a/project_files/Android-build/SDL-android-project/res/raw/scheme_tunnelhogs.ini Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -[Scheme] -name=Tunnelhogs - -[BasicSettings] -DamagePercent=100 -TurnTime=30 -InitialHealth=100 -SuddenDeathTimeout=15 -CrateDropTurns=5 -MinesTime=3 -MinesNumber=10 -MinesDudPercent=10 -Explosives=10 -HealthCratePercent=35 -HealthCrateHP=25 -SuddenDeathWaterRise=47 -SuddenDeathHealthDecrease=5 -RopeLengthPercent=100 -GetAwayTimePercent=100 - -[GameMods] -SolidLand=false -Border=false -DivideTeams=true -LowGravity=false -LaserSight=false -Invulnerable=false -ResetHealth=false -Vampiric=false -Karma=false -Artillery=false -Forts=false -RandomOrder=true -King=false -PlaceHog=false -SharedAmmo=true -DisableGirders=true -DisableLandObjects=true -AISurvival=false -InfAttack=false -ResetWeps=false -PerHogAmmo=false -DisableWind=false -MoreWind=false -TagTeam=false -BottomBorder=false diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/schemes_builtin.ini --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/res/raw/schemes_builtin.ini Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,456 @@ + +[schemes] +size = 11 +1\name = Default +1\fortsmode = false +1\divteams = false +1\solidland = false +1\border = false +1\lowgrav = false +1\laser = false +1\invulnerability = false +1\resethealth = false +1\vampiric = false +1\karma = false +1\artillery = false +1\randomorder = false +1\king = false +1\placehog = false +1\sharedammo = false +1\disablegirders = false +1\disablelandobjects = false +1\aisurvival = false +1\infattack = false +1\resetweps = false +1\perhogammo = false +1\disablewind = false +1\morewind = false +1\tagteam = false +1\bottomborder = false +1\damagefactor = 100 +1\turntime = 45 +1\health = 100 +1\suddendeath = 15 +1\caseprobability = 5 +1\minestime = 3 +1\minesnum = 4 +1\minedudpct = 0 +1\explosives = 2 +1\healthprobability = 35 +1\healthcaseamount = 25 +1\waterrise = 47 +1\healthdecrease = 5 +1\ropepct = 100 +1\getawaytime = 100 +2\name = Pro Mode +2\fortsmode = false +2\divteams = false +2\solidland = false +2\border = false +2\lowgrav = false +2\laser = false +2\invulnerability = false +2\resethealth = false +2\vampiric = false +2\karma = false +2\artillery = false +2\randomorder = true +2\king = false +2\placehog = false +2\sharedammo = false +2\disablegirders = false +2\disablelandobjects = false +2\aisurvival = false +2\infattack = false +2\resetweps = false +2\perhogammo = false +2\disablewind = false +2\morewind = false +2\tagteam = false +2\bottomborder = false +2\damagefactor = 100 +2\turntime = 45 +2\health = 100 +2\suddendeath = 15 +2\caseprobability = 5 +2\minestime = 3 +2\minesnum = 4 +2\minedudpct = 0 +2\explosives = 2 +2\healthprobability = 35 +2\healthcaseamount = 25 +2\waterrise = 47 +2\healthdecrease = 5 +2\ropepct = 100 +2\getawaytime = 100 +3\name = Shoppa +3\fortsmode = false +3\divteams = false +3\solidland = false +3\border = false +3\lowgrav = false +3\laser = false +3\invulnerability = false +3\resethealth = false +3\vampiric = false +3\karma = false +3\artillery = false +3\randomorder = true +3\king = false +3\placehog = false +3\sharedammo = true +3\disablegirders = false +3\disablelandobjects = false +3\aisurvival = false +3\infattack = false +3\resetweps = false +3\perhogammo = false +3\disablewind = false +3\morewind = false +3\tagteam = false +3\bottomborder = false +3\damagefactor = 100 +3\turntime = 15 +3\health = 100 +3\suddendeath = 15 +3\caseprobability = 0 +3\minestime = 3 +3\minesnum = 0 +3\minedudpct = 0 +3\explosives = 2 +3\healthprobability = 35 +3\healthcaseamount = 25 +3\waterrise = 47 +3\healthdecrease = 5 +3\ropepct = 100 +3\getawaytime = 100 +4\name = Clean Slate +4\fortsmode = false +4\divteams = false +4\solidland = true +4\border = true +4\lowgrav = false +4\laser = false +4\invulnerability = false +4\resethealth = false +4\vampiric = false +4\karma = false +4\artillery = false +4\randomorder = true +4\king = false +4\placehog = false +4\sharedammo = true +4\disablegirders = true +4\disablelandobjects = false +4\aisurvival = false +4\infattack = false +4\resetweps = true +4\perhogammo = false +4\disablewind = false +4\morewind = false +4\tagteam = false +4\bottomborder = false +4\damagefactor = 100 +4\turntime = 30 +4\health = 100 +4\suddendeath = 50 +4\caseprobability = 1 +4\minestime = 3 +4\minesnum = 0 +4\minedudpct = 0 +4\explosives = 0 +4\healthprobability = 0 +4\healthcaseamount = 25 +4\waterrise = 47 +4\healthdecrease = 5 +4\ropepct = 100 +4\getawaytime = 100 +5\name = Minefield +5\fortsmode = false +5\divteams = false +5\solidland = false +5\border = false +5\lowgrav = false +5\laser = false +5\invulnerability = false +5\resethealth = true +5\vampiric = false +5\karma = false +5\artillery = false +5\randomorder = true +5\king = false +5\placehog = false +5\sharedammo = false +5\disablegirders = false +5\disablelandobjects = false +5\aisurvival = false +5\infattack = true +5\resetweps = true +5\perhogammo = false +5\disablewind = false +5\morewind = false +5\tagteam = false +5\bottomborder = false +5\damagefactor = 100 +5\turntime = 45 +5\health = 100 +5\suddendeath = 15 +5\caseprobability = 5 +5\minestime = 3 +5\minesnum = 4 +5\minedudpct = 0 +5\explosives = 2 +5\healthprobability = 35 +5\healthcaseamount = 25 +5\waterrise = 47 +5\healthdecrease = 5 +5\ropepct = 100 +5\getawaytime = 100 +6\name = Barrel Mayhem +6\fortsmode = false +6\divteams = false +6\solidland = false +6\border = false +6\lowgrav = false +6\laser = false +6\invulnerability = false +6\resethealth = false +6\vampiric = false +6\karma = false +6\artillery = false +6\randomorder = true +6\king = false +6\placehog = false +6\sharedammo = true +6\disablegirders = true +6\disablelandobjects = false +6\aisurvival = false +6\infattack = false +6\resetweps = false +6\perhogammo = false +6\disablewind = false +6\morewind = false +6\tagteam = false +6\bottomborder = false +6\damagefactor = 100 +6\turntime = 30 +6\health = 50 +6\suddendeath = 15 +6\caseprobability = 0 +6\minestime = 0 +6\minesnum = 80 +6\minedudpct = 0 +6\explosives = 0 +6\healthprobability = 35 +6\healthcaseamount = 25 +6\waterrise = 47 +6\healthdecrease = 5 +6\ropepct = 100 +6\getawaytime = 100 +7\name = Tunnel Hogs +7\fortsmode = false +7\divteams = false +7\solidland = false +7\border = false +7\lowgrav = false +7\laser = false +7\invulnerability = false +7\resethealth = false +7\vampiric = false +7\karma = false +7\artillery = false +7\randomorder = true +7\king = false +7\placehog = false +7\sharedammo = true +7\disablegirders = false +7\disablelandobjects = false +7\aisurvival = false +7\infattack = false +7\resetweps = false +7\perhogammo = false +7\disablewind = false +7\morewind = false +7\tagteam = false +7\bottomborder = false +7\damagefactor = 100 +7\turntime = 30 +7\health = 100 +7\suddendeath = 15 +7\caseprobability = 0 +7\minestime = 0 +7\minesnum = 0 +7\minedudpct = 0 +7\explosives = 80 +7\healthprobability = 35 +7\healthcaseamount = 25 +7\waterrise = 47 +7\healthdecrease = 5 +7\ropepct = 100 +7\getawaytime = 100 +8\name = Fort Mode +8\fortsmode = false +8\divteams = false +8\solidland = false +8\border = true +8\lowgrav = false +8\laser = false +8\invulnerability = false +8\resethealth = false +8\vampiric = false +8\karma = false +8\artillery = false +8\randomorder = true +8\king = false +8\placehog = false +8\sharedammo = true +8\disablegirders = true +8\disablelandobjects = true +8\aisurvival = false +8\infattack = false +8\resetweps = false +8\perhogammo = false +8\disablewind = false +8\morewind = false +8\tagteam = false +8\bottomborder = false +8\damagefactor = 100 +8\turntime = 30 +8\health = 100 +8\suddendeath = 15 +8\caseprobability = 5 +8\minestime = 3 +8\minesnum = 10 +8\minedudpct = 10 +8\explosives = 10 +8\healthprobability = 35 +8\healthcaseamount = 25 +8\waterrise = 47 +8\healthdecrease = 5 +8\ropepct = 100 +8\getawaytime = 100 +9\name = Timeless +9\fortsmode = true +9\divteams = true +9\solidland = false +9\border = false +9\lowgrav = true +9\laser = false +9\invulnerability = false +9\resethealth = false +9\vampiric = false +9\karma = false +9\artillery = false +9\randomorder = true +9\king = false +9\placehog = false +9\sharedammo = false +9\disablegirders = false +9\disablelandobjects = false +9\aisurvival = false +9\infattack = false +9\resetweps = false +9\perhogammo = false +9\disablewind = false +9\morewind = false +9\tagteam = false +9\bottomborder = false +9\damagefactor = 100 +9\turntime = 45 +9\health = 100 +9\suddendeath = 15 +9\caseprobability = 5 +9\minestime = 3 +9\minesnum = 0 +9\minedudpct = 0 +9\explosives = 0 +9\healthprobability = 35 +9\healthcaseamount = 25 +9\waterrise = 47 +9\healthdecrease = 5 +9\ropepct = 100 +9\getawaytime = 100 +10\name = Thinking with Portals +10\fortsmode = false +10\divteams = false +10\solidland = false +10\border = false +10\lowgrav = false +10\laser = false +10\invulnerability = false +10\resethealth = false +10\vampiric = false +10\karma = false +10\artillery = false +10\randomorder = true +10\king = false +10\placehog = false +10\sharedammo = false +10\disablegirders = false +10\disablelandobjects = false +10\aisurvival = false +10\infattack = false +10\resetweps = false +10\perhogammo = true +10\disablewind = false +10\morewind = false +10\tagteam = false +10\bottomborder = false +10\damagefactor = 100 +10\turntime = 9999 +10\health = 100 +10\suddendeath = 15 +10\caseprobability = 5 +10\minestime = 3 +10\minesnum = 5 +10\minedudpct = 10 +10\explosives = 2 +10\healthprobability = 35 +10\healthcaseamount = 30 +10\waterrise = 0 +10\healthdecrease = 0 +10\ropepct = 100 +10\getawaytime = 100 +11\name = King Mode +11\fortsmode = false +11\divteams = false +11\solidland = false +11\border = false +11\lowgrav = false +11\laser = false +11\invulnerability = false +11\resethealth = false +11\vampiric = false +11\karma = false +11\artillery = true +11\randomorder = true +11\king = false +11\placehog = false +11\sharedammo = false +11\disablegirders = false +11\disablelandobjects = false +11\aisurvival = false +11\infattack = false +11\resetweps = false +11\perhogammo = false +11\disablewind = false +11\morewind = false +11\tagteam = false +11\bottomborder = false +11\damagefactor = 100 +11\turntime = 45 +11\health = 100 +11\suddendeath = 15 +11\caseprobability = 2 +11\minestime = 3 +11\minesnum = 5 +11\minedudpct = 0 +11\explosives = 5 +11\healthprobability = 25 +11\healthcaseamount = 25 +11\waterrise = 47 +11\healthdecrease = 5 +11\ropepct = 100 +11\getawaytime = 100 + + diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/team_one.hwt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/res/raw/team_one.hwt Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,74 @@ +[Team] +Name=Team 1 +Grave=Bone +Fort=Lego +Voicepack=Classic +Flag=hedgewars +Difficulty=0 +Rounds=0 +Wins=0 +CampaignProgress=0 + +[Hedgehog0] +Name=Leonidas +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog1] +Name=Pipo +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog2] +Name=Sonic +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog3] +Name=Xin +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog4] +Name=Arnold +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog5] +Name=Jack +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog6] +Name=Tom +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog7] +Name=Goldie +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/team_one.xml --- a/project_files/Android-build/SDL-android-project/res/raw/team_one.xml Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ - - - Team 1 - hedgewars - Lego - Bone - Classic - 0 - - Leonidas - NoHat - 0 - - - Pipo - NoHat - 0 - - - Sonic - NoHat - 0 - - - Xin - NoHat - 0 - - - Arnold - NoHat - 0 - - - Jack - NoHat - 0 - - - Tom - NoHat - 0 - - - Goldie - NoHat - 0 - - \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/team_two.hwt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/res/raw/team_two.hwt Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,74 @@ +[Team] +Name=Team 2 +Grave=Bone +Fort=Lego +Voicepack=Classic +Flag=cm_binary +Difficulty=2 +Rounds=0 +Wins=0 +CampaignProgress=0 + +[Hedgehog0] +Name=Paris +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog1] +Name=Knut +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog2] +Name=Ash +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog3] +Name=Woad +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog4] +Name=Bob +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog5] +Name=Corky +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog6] +Name=Bea +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 + +[Hedgehog7] +Name=Silvia +Hat=NoHat +Rounds=0 +Kills=0 +Deaths=0 +Suicides=0 diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/raw/team_two.xml --- a/project_files/Android-build/SDL-android-project/res/raw/team_two.xml Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ - - - Team 2 - cm_binary - Lego - Bone - Classic - 0 - - Paris - NoHat - 2 - - - Knut - NoHat - 2 - - - Ash - NoHat - 2 - - - Woad - NoHat - 2 - - - Bob - NoHat - 2 - - - Corky - NoHat - 2 - - - Bea - NoHat - 2 - - - Silvia - NoHat - 2 - - \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml --- a/project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml Mon Aug 06 22:39:36 2012 +0200 @@ -1,22 +1,6 @@ - - @raw/basicsettings - @raw/gamemods - @raw/scheme_default_scheme - @raw/scheme_barrelmayhem - @raw/scheme_cleanslate - @raw/scheme_fortmode - @raw/scheme_kingmode - @raw/scheme_minefield - @raw/scheme_promode - @raw/scheme_shoppa - @raw/scheme_thinkingwithportals - @raw/scheme_timeless - @raw/scheme_tunnelhogs - - @raw/weapon_default @raw/weapon_clean @@ -30,6 +14,5 @@ @raw/team_one @raw/team_two - diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/res/values/strings.xml --- a/project_files/Android-build/SDL-android-project/res/values/strings.xml Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/res/values/strings.xml Mon Aug 06 22:39:36 2012 +0200 @@ -104,6 +104,7 @@ Please select a username. Username + Kick Info (shown in chat) Follow Create room @@ -121,6 +122,8 @@ The server you tried to connect to is using an incompatible protocol. Unable to authenticate for your username. The connection to the server was lost. + Saving has failed. + Please wait diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java Mon Aug 06 22:39:36 2012 +0200 @@ -26,13 +26,13 @@ import java.util.List; import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.StartGameActivity; import org.hedgewars.hedgeroid.Utils; import org.hedgewars.hedgeroid.Datastructures.Map.MapType; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import java.nio.ByteBuffer; public class FrontendDataUtils { @@ -73,16 +73,11 @@ return list; } - public static List getSchemes(Context c){ - List list = Scheme.getSchemes(c); - Collections.sort(list); - return list; - } - public static List getWeapons(Context c){ - List list = Weapon.getWeapons(c); - Collections.sort(list); - return list; + // TODO stub, re-implement + /*List list = Weapon.getWeapons(c); + Collections.sort(list);*/ + return Collections.emptyList(); } public static ArrayList> getGraves(Context c){ @@ -171,50 +166,24 @@ return data; } - public static List> getTeams(Context c){ - List> ret = new ArrayList>(); - - File teamsDir = new File(c.getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS); + public static List getTeamFiles(Context c) { + List ret = new ArrayList(); + + File teamsDir = new File(c.getFilesDir(), Team.DIRECTORY_TEAMS); File[] teamFileNames = teamsDir.listFiles(); if(teamFileNames != null){ - for(File s : teamFileNames){ - Team t = Team.getTeamFromXml(s.getAbsolutePath()); - if(t != null){ - t.file = s.getName(); - ret.add(teamToMap(t)); + for(File file : teamFileNames){ + Team team = Team.load(file); + if(team != null){ + ret.add(new TeamFile(team, file)); } } } return ret; } - public static HashMap teamToMap(Team t){ - HashMap hashmap = new HashMap(); - hashmap.put("team", t); - hashmap.put("txt", t.name); - hashmap.put("color", t.color); - hashmap.put("count", t.hogCount); - switch(t.levels[0]){ - case 0: - hashmap.put("img", R.drawable.human); - break; - case 1: - hashmap.put("img", R.drawable.bot5); - break; - case 2: - hashmap.put("img", R.drawable.bot4); - break; - case 3: - hashmap.put("img", R.drawable.bot3); - break; - case 4: - hashmap.put("img", R.drawable.bot2); - break; - default: - case 5: - hashmap.put("img", R.drawable.bot1); - break; - } - return hashmap; + public static Scheme[] getSchemes(StartGameActivity startGameActivity) { + // TODO Auto-generated method stub + return null; } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java Mon Aug 06 22:39:36 2012 +0200 @@ -20,5 +20,5 @@ package org.hedgewars.hedgeroid.Datastructures; public enum GameMode { - MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE + MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java Mon Aug 06 22:39:36 2012 +0200 @@ -19,18 +19,17 @@ package org.hedgewars.hedgeroid.Datastructures; -public class Grave{ - +public final class Grave{ public final String name; public final String path; - public Grave(String _name, String _path) { - name = _name; - path = _path; + public Grave(String name, String path) { + this.name = name; + this.path = path; } - public String toString(){ - return name; + @Override + public String toString() { + return "Grave [name=" + name + ", path=" + path + "]"; } - } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Hog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Hog.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,17 @@ +package org.hedgewars.hedgeroid.Datastructures; + +public final class Hog { + public final String name, hat; + public final int level; + + public Hog(String name, String hat, int level) { + this.name = name; + this.hat = hat; + this.level = level; + } + + @Override + public String toString() { + return "Hog [name=" + name + ", hat=" + hat + ", level=" + level + "]"; + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java Mon Aug 06 22:39:36 2012 +0200 @@ -19,17 +19,11 @@ package org.hedgewars.hedgeroid.Datastructures; import java.io.File; -import java.io.IOException; - -import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork; - import android.content.Context; import android.graphics.drawable.Drawable; -import android.os.Parcel; -import android.os.Parcelable; -public class Map implements Comparable, Parcelable{ +public class Map implements Comparable { private static final String MISSION_PREFIX = "Mission: "; @@ -60,10 +54,6 @@ } - - public Map(Parcel in){ - readFromParcel(in); - } public String toString(){ switch(type){ @@ -77,10 +67,6 @@ } } - public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ - epn.sendToEngine(String.format("emap %s",name)); - } - public MapType getType(){ return type; } @@ -133,31 +119,4 @@ public enum MapType{ TYPE_DEFAULT, TYPE_MISSION, TYPE_GENERATED } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeString(path); - dest.writeString(previewPath); - dest.writeString(type.name()); - } - - private void readFromParcel(Parcel src){ - name = src.readString(); - path = src.readString(); - previewPath = src.readString(); - type = MapType.valueOf(src.readString()); - } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Map createFromParcel(Parcel source) { - return new Map(source); - } - public Map[] newArray(int size) { - return new Map[size]; - } - - }; } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MetaScheme.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MetaScheme.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,59 @@ +package org.hedgewars.hedgeroid.Datastructures; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class MetaScheme { + public static final class Mod { + public final String name; + public final int bitmaskIndex; + + public Mod(String name, int bitmaskIndex) { + this.name = name; + this.bitmaskIndex = bitmaskIndex; + } + + @Override + public String toString() { + return "MetaScheme$Mod [name=" + name + ", bitmaskIndex=" + bitmaskIndex + "]"; + } + } + + public static final class Setting { + public final String name, engineCommand; + public final boolean maxMeansInfinity, times1000; + public final int min, max, def; + + public Setting(String name, String engineCommand, boolean maxMeansInfinity, boolean times1000, int min, int max, int def) { + this.name = name; + this.engineCommand = engineCommand; + this.maxMeansInfinity = maxMeansInfinity; + this.times1000 = times1000; + this.min = min; + this.max = max; + this.def = def; + } + + @Override + public String toString() { + return "MetaScheme$Setting [name=" + name + ", engineCommand=" + engineCommand + + ", maxMeansInfinite=" + maxMeansInfinity + ", times1000=" + + times1000 + ", min=" + min + ", max=" + max + ", def=" + + def + "]"; + } + } + + public final List mods; + public final List settings; + + public MetaScheme(List mods, List settings) { + this.mods = Collections.unmodifiableList(new ArrayList(mods)); + this.settings = Collections.unmodifiableList(new ArrayList(settings)); + } + + @Override + public String toString() { + return "MetaScheme [\nmods=" + mods + ", \nsettings=" + settings + "\n]"; + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Player.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Player.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,14 @@ +package org.hedgewars.hedgeroid.Datastructures; + +public final class Player { + public final String name; + + public Player(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Player [name=" + name + "]"; + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/RoomlistRoom.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/RoomlistRoom.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,52 @@ +package org.hedgewars.hedgeroid.Datastructures; + +import org.hedgewars.hedgeroid.R; + +import android.content.res.Resources; + +public final class RoomlistRoom { + public static final String MAP_REGULAR = "+rnd+"; + public static final String MAP_MAZE = "+maze+"; + public static final String MAP_DRAWN = "+drawn+"; + + public final String name, map, scheme, weapons, owner; + public final int playerCount, teamCount; + public final boolean inProgress; + + public RoomlistRoom(String name, String map, String scheme, String weapons, + String owner, int playerCount, int teamCount, boolean inProgress) { + this.name = name; + this.map = map; + this.scheme = scheme; + this.weapons = weapons; + this.owner = owner; + this.playerCount = playerCount; + this.teamCount = teamCount; + this.inProgress = inProgress; + } + + public static String formatMapName(Resources res, String map) { + if(map.charAt(0)=='+') { + if(map.equals(MAP_REGULAR)) { + return res.getString(R.string.map_regular); + } else if(map.equals(MAP_MAZE)) { + return res.getString(R.string.map_maze); + } else if(map.equals(MAP_DRAWN)) { + return res.getString(R.string.map_drawn); + } + } + return map; + } + + public String formatMapName(Resources res) { + return formatMapName(res, map); + } + + @Override + public String toString() { + return "RoomlistRoom [name=" + name + ", map=" + map + ", scheme=" + + scheme + ", weapons=" + weapons + ", owner=" + owner + + ", playerCount=" + playerCount + ", teamCount=" + teamCount + + ", inProgress=" + inProgress + "]"; + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java Mon Aug 06 22:39:36 2012 +0200 @@ -19,247 +19,37 @@ package org.hedgewars.hedgeroid.Datastructures; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.Map; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map.Entry; -import java.util.TreeMap; - -import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork; -import org.ini4j.Ini; -import org.ini4j.InvalidFileFormatException; -import org.ini4j.Profile.Section; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -public class Scheme implements Parcelable, Comparable{ - public static final String DIRECTORY_SCHEME = "schemes"; - private static final Map basicSettingsMeta = new TreeMap(); - private static final Map gameModsMeta = new TreeMap(); - - private final String name; - private final int gamemod; - private final Map basic = new TreeMap(); +public final class Scheme { + public final MetaScheme metascheme; + public final String name; + public final Map settings; + public final Map mods; - public Scheme(String _name, Map _basic, int _gamemod) { - name = _name; - gamemod = _gamemod; - basic.putAll(_basic); - } - - public Scheme(Parcel in){ - name = in.readString(); - gamemod = in.readInt(); - in.readMap(basic, Integer.class.getClassLoader()); - } - - public int getHealth() { - return basic.get("InitialHealth"); - } - - public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ - epn.sendToEngine(String.format("e$gmflags %d", gamemod)); - - for(Map.Entry entry : basic.entrySet()) { - BasicSettingMeta basicflag = basicSettingsMeta.get(entry.getKey()); - - //Health is a special case, it doesn't need to be send - //to the engine yet, we'll do that with the other HH info - if(!basicflag.command.equals("inithealth")){ - epn.sendToEngine(String.format("%s %d", basicflag.command, entry.getValue())); - } - } + public Scheme(MetaScheme metascheme, String name, Map settings, Map mods) { + this.metascheme = metascheme; + this.name = name; + this.settings = Collections.unmodifiableMap(new HashMap(settings)); + this.mods = Collections.unmodifiableMap(new HashMap(mods)); } - public String toString(){ - return name; - } - - public static List getSchemes(Context c) throws IllegalArgumentException { - File schemeDir = new File(c.getFilesDir(), DIRECTORY_SCHEME); - File[] files = schemeDir.listFiles(new FilenameFilter() { - public boolean accept(File dir, String filename) { - return filename.toLowerCase().startsWith("scheme_"); - } - }); - if(files == null) files = new File[0]; - Arrays.sort(files); - List schemes = new ArrayList(); - - for(File file : files) { - try { - Ini ini = new Ini(file); - - String name = ini.get("Scheme", "name"); - if(name==null) { - name = file.getName(); - } - Section basicSettingsSection = ini.get("BasicSettings"); - Section gameModsSection = ini.get("GameMods"); - if(basicSettingsSection == null || gameModsSection == null) { - Log.e(Scheme.class.getCanonicalName(), "Scheme file "+file+" is missing the BasicSettings or GameMods section - skipping."); - continue; - } - - Map basicSettings = new TreeMap(); - for(Entry entry : basicSettingsMeta.entrySet()) { - String key = entry.getKey(); - BasicSettingMeta settingMeta = entry.getValue(); - Integer value = null; - if(basicSettingsSection.containsKey(key)) { - try { - value = Integer.valueOf(basicSettingsSection.get(key)); - } catch (NumberFormatException e) { - // ignore - } - } - - if(value==null) { - Log.w(Scheme.class.getCanonicalName(), "Scheme file "+file+" setting "+key+" is missing or invalid, using default."); - value = settingMeta.def; - } - - if(settingMeta.checkOverMax) { - value = Math.min(value, settingMeta.max); - } - if(settingMeta.times1000) { - value *= 1000; - } - - basicSettings.put(key, value); - } - - int gamemods = 0; - for(Entry entry : gameModsMeta.entrySet()) { - String key = entry.getKey(); - GameModMeta modMeta = entry.getValue(); - if(Boolean.parseBoolean(gameModsSection.get(key))) { - gamemods |= (1 << modMeta.bitmaskIndex); - } - } - - schemes.add(new Scheme(name, basicSettings, gamemods)); - } catch (InvalidFileFormatException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - return schemes; - } - - /** - * This method will parse the basic flags from a prespecified ini file. - * In the future we could use one provided by the Data folder. - */ - public static void parseConfiguration(Context c) { - File schemeDir = new File(c.getFilesDir(), DIRECTORY_SCHEME); - File settingsFile = new File(schemeDir, "basicsettings"); - File gameModsFile = new File(schemeDir, "gamemods"); - - try { - Ini ini = new Ini(settingsFile); - for(Entry sectionEntry : ini.entrySet()) { - basicSettingsMeta.put(sectionEntry.getKey(), new BasicSettingMeta(sectionEntry.getValue())); - } - - ini = new Ini(gameModsFile); - for(Entry sectionEntry : ini.entrySet()) { - gameModsMeta.put(sectionEntry.getKey(), new GameModMeta(sectionEntry.getValue())); - } - } catch (InvalidFileFormatException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeInt(gamemod); - dest.writeMap(basic); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Scheme createFromParcel(Parcel source) { - return new Scheme(source); - } - public Scheme[] newArray(int size) { - return new Scheme[size]; - } - - }; - - public int compareTo(Scheme another) { - return name.compareTo(another.name); - } -} - -class BasicSettingMeta { - final String command; - final String title; - final int def; - final int min; - final int max; - final boolean times1000; - final boolean checkOverMax; - - public BasicSettingMeta(Ini.Section section) { - command = getRequired(section, "command"); - title = section.get("title", ""); - def = Integer.parseInt(getRequired(section, "default")); - min = Integer.parseInt(getRequired(section, "min")); - max = Integer.parseInt(getRequired(section, "max")); - times1000 = Boolean.parseBoolean(section.get("times1000", "false")); - checkOverMax = Boolean.parseBoolean(section.get("checkOverMax", "false")); - } - - private String getRequired(Ini.Section section, String key) { - String result = section.get(key); - if(result==null) { - throw new IllegalArgumentException("basicsettings.ini, section "+section.getName()+" is missing required setting "+key+"."); - } - return result; + public int getHealth() { + return settings.get("health"); } @Override public String toString() { - return String - .format("BasicSettingMeta [command=%s, title=%s, def=%s, min=%s, max=%s, times1000=%s, checkOverMax=%s]", - command, title, def, min, max, times1000, checkOverMax); - } -} - -// TODO: Extend with additional metadata -class GameModMeta { - final int bitmaskIndex; - - public GameModMeta(Ini.Section section) { - bitmaskIndex = Integer.parseInt(getRequired(section, "bitmaskIndex")); + return "Scheme [metascheme=" + metascheme + ", name=" + name + + ", settings=" + settings + ", mods=" + mods + "]"; } - private String getRequired(Ini.Section section, String key) { - String result = section.get(key); - if(result==null) { - throw new IllegalArgumentException("gamemods.ini, section "+section.getName()+" is missing required setting "+key+"."); + public static final Comparator caseInsensitiveNameComparator = new Comparator() { + public int compare(Scheme lhs, Scheme rhs) { + return lhs.name.compareToIgnoreCase(rhs.name); } - return result; - } - - @Override - public String toString() { - return String.format("GameModMeta [bitmaskIndex=%s]", bitmaskIndex); - } + }; } \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Schemes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Schemes.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,82 @@ +package org.hedgewars.hedgeroid.Datastructures; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.hedgewars.hedgeroid.Utils; +import org.hedgewars.hedgeroid.frontlib.Flib; +import org.hedgewars.hedgeroid.frontlib.Frontlib.MetaschemePtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.SchemelistPtr; + +import android.content.Context; + +/** + * Functions for handling the persistent list of schemes. + * Schemes in that list are identified by name (case sensitive). + */ +public final class Schemes { + private Schemes() { + throw new AssertionError("This class is not meant to be instantiated"); + } + + public static File getUserSchemesFile(Context c) { + return new File(c.getFilesDir(), "schemes_user.ini"); + } + + public static File getBuiltinSchemesFile(Context c) { + return new File(c.getFilesDir(), "schemes_builtin.ini"); + } + + public static Map loadUserSchemes(Context c) throws IOException { + return loadSchemes(c, getUserSchemesFile(c)); + } + + public static Map loadBuiltinSchemes(Context c) throws IOException { + return loadSchemes(c, getBuiltinSchemesFile(c)); + } + + public static Map loadSchemes(Context c, File schemeFile) throws IOException { + Map result = new TreeMap(); + String metaschemePath = new File(Utils.getDataPathFile(c), "metasettings.ini").getAbsolutePath(); + if(!schemeFile.isFile()) { + // No schemes file == no schemes, no error + return new TreeMap(); + } + MetaschemePtr meta = null; + SchemelistPtr schemeListPtr = null; + try { + meta = Flib.INSTANCE.flib_metascheme_from_ini(metaschemePath); + if(meta==null) { + throw new IOException("Unable to read metascheme"); + } + schemeListPtr = Flib.INSTANCE.flib_schemelist_from_ini(meta, schemeFile.getAbsolutePath()); + if(schemeListPtr == null) { + throw new IOException("Unable to read schemelist"); + } + List schemeList = schemeListPtr.deref(); + for(Scheme scheme : schemeList) { + result.put(scheme.name, scheme); + } + return result; + } finally { + if(schemeListPtr != null) { + Flib.INSTANCE.flib_schemelist_destroy(schemeListPtr); + } + if(meta != null) { + Flib.INSTANCE.flib_metascheme_release(meta); + } + } + } + + public static void saveUserSchemes(Context c, Map schemes) throws IOException { + List schemeList = new ArrayList(schemes.values()); + Collections.sort(schemeList, Scheme.caseInsensitiveNameComparator); + SchemelistPtr ptr = SchemelistPtr.createJavaOwned(schemeList); + Flib.INSTANCE.flib_schemelist_to_ini(getUserSchemesFile(c).getAbsolutePath(), ptr); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java Mon Aug 06 22:39:36 2012 +0200 @@ -18,365 +18,62 @@ package org.hedgewars.hedgeroid.Datastructures; -import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; -import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; -import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork; import org.hedgewars.hedgeroid.EngineProtocol.PascalExports; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; -import org.xmlpull.v1.XmlSerializer; +import org.hedgewars.hedgeroid.frontlib.Flib; +import org.hedgewars.hedgeroid.frontlib.Frontlib.TeamPtr; -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Xml; +import android.util.Log; -public class Team implements Parcelable{ - +public final class Team { public static final String DIRECTORY_TEAMS = "teams"; - private static final Integer[] TEAM_COLORS = { - 0xd12b42, /* red */ - 0x4980c1, /* blue */ - 0x6ab530, /* green */ - 0xbc64c4, /* purple */ - 0xe76d14, /* orange */ - 0x3fb6e6, /* cyan */ - 0xe3e90c, /* yellow */ - 0x61d4ac, /* mint */ - 0xf1c3e1, /* pink */ - /* add new colors here */ - }; -// private static final Integer[] TEAM_COLORS = { -// 0xff0000, /* red */ -// 0x00ff00, /* blue */ -// 0x0000ff, /* green */ -// }; + public static final int maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs(); + public static final int maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams(); + + public final String name, grave, flag, voice, fort; + public final List hogs; - private static final int STATE_START = 0; - private static final int STATE_ROOT = 1; - private static final int STATE_HOG_ROOT = 2; - - public String name, grave, flag, voice, fort, hash; - public String file = null; - - public static int maxNumberOfHogs = 0; - public static int maxNumberOfTeams = 0; - - static{ - maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs(); - maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams(); - } - public String[] hats = new String[maxNumberOfHogs]; - public String[] hogNames = new String[maxNumberOfHogs]; - public int[] levels = new int[maxNumberOfHogs]; - - public int hogCount = 4; - public int color = TEAM_COLORS[0]; - - public Team(){ + public Team(String name, String grave, String flag, String voice, String fort, List hogs) { + if(hogs.size() != maxNumberOfHogs) { + throw new IllegalArgumentException("A team must consist of "+maxNumberOfHogs+" hogs."); + } + this.name = name; + this.grave = grave; + this.flag = flag; + this.voice = voice; + this.fort = fort; + this.hogs = Collections.unmodifiableList(new ArrayList(hogs)); } - public Team(Parcel in){ - readFromParcel(in); - } - - @Override - public boolean equals(Object o){ - if(super.equals(o)) return true; - else if(o instanceof Team){ - Team t = (Team)o; - boolean ret = name.equals(t.name); - ret &= grave.equals(t.grave); - ret &= flag.equals(t.flag); - ret &= voice.equals(t.voice); - ret &= fort.equals(t.fort); - ret &= hash.equals(t.hash); - return ret; - }else{ - return false; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((grave == null) ? 0 : grave.hashCode()); - result = prime * result + ((flag == null) ? 0 : flag.hashCode()); - result = prime * result + ((voice == null) ? 0 : voice.hashCode()); - result = prime * result + ((fort == null) ? 0 : fort.hashCode()); - result = prime * result + ((hash == null) ? 0 : hash.hashCode()); - return result; - } - - public void setRandomColor(int[] illegalcolors){ - Integer[] colorsToPickFrom = TEAM_COLORS; - if(illegalcolors != null){ - ArrayList colors = new ArrayList(); - for(int color : TEAM_COLORS){ - boolean validColor = true; - for(int illegal : illegalcolors){ - if(color == illegal) validColor = false; - } - if(validColor) colors.add(color); - } - if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]); - } - int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1)); - color = colorsToPickFrom[index]; - } - - - public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{ - epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name)); - epn.sendToEngine(String.format("egrave %s", grave)); - epn.sendToEngine(String.format("efort %s", fort)); - epn.sendToEngine(String.format("evoicepack %s", voice)); - epn.sendToEngine(String.format("eflag %s", flag)); - - for(int i = 0; i < hogCount; i++){ - epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i])); - epn.sendToEngine(String.format("ehat %s", hats[i])); + public void save(File f) throws IOException { + Log.d("Team", "saving to "+f.getAbsolutePath()); + TeamPtr teamPtr = TeamPtr.createJavaOwned(this); + if(Flib.INSTANCE.flib_team_to_ini(f.getAbsolutePath(), teamPtr) != 0) { + throw new IOException("Error saving team "+name); } } - public void setFileName(Context c){ - if(file == null){ - file = validFileName(c, name); - } - } - private String validFileName(Context c, String fileName){ - String absolutePath = String.format("%s/%s", c.getFilesDir(), fileName); - File f = new File(absolutePath); - if(f.exists()){ - String newFileName = fileName + (int)(Math.random()*10); - return validFileName(c, newFileName); - }else{ - return fileName; + public static Team load(File f) { + TeamPtr teamPtr = Flib.INSTANCE.flib_team_from_ini(f.getAbsolutePath()); + if(teamPtr != null) { + Team team = teamPtr.deref().team; + Flib.INSTANCE.flib_team_destroy(teamPtr); + return team; + } else { + return null; } } - - /* - * XML METHODS - */ - - /** - * Read the xml file path and convert it to a Team object - * @param path absolute path to the xml file - * @return - */ - public static Team getTeamFromXml(String path){ - try { - XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); - XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); - - BufferedReader br = new BufferedReader(new FileReader(path), 1024); - xmlPuller.setInput(br); - Team team = new Team(); - int hogCounter = 0; - - int eventType = xmlPuller.getEventType(); - int state = STATE_START; - while(eventType != XmlPullParser.END_DOCUMENT){ - switch(state){ - case STATE_START: - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT; - else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType); - break; - case STATE_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("name")){ - team.name = getXmlText(xmlPuller, "name"); - }else if(xmlPuller.getName().toLowerCase().equals("flag")){ - team.flag= getXmlText(xmlPuller, "flag"); - }else if(xmlPuller.getName().toLowerCase().equals("voice")){ - team.voice = getXmlText(xmlPuller, "voice"); - }else if(xmlPuller.getName().toLowerCase().equals("grave")){ - team.grave = getXmlText(xmlPuller, "grave"); - }else if(xmlPuller.getName().toLowerCase().equals("fort")){ - team.fort = getXmlText(xmlPuller, "fort"); - }else if(xmlPuller.getName().toLowerCase().equals("hash")){ - team.hash = getXmlText(xmlPuller, "hash"); - }else if(xmlPuller.getName().toLowerCase().equals("hog")){ - state = STATE_HOG_ROOT; - }else throwException(xmlPuller.getName(), eventType); - }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; - else throwException(xmlPuller.getText(), eventType); - break; - case STATE_HOG_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("name")){ - team.hogNames[hogCounter] = getXmlText(xmlPuller, "name"); - }else if(xmlPuller.getName().toLowerCase().equals("hat")){ - team.hats[hogCounter] = getXmlText(xmlPuller, "hat"); - }else if(xmlPuller.getName().toLowerCase().equals("level")){ - team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level")); - }else throwException(xmlPuller.getText(), eventType); - }else if(eventType == XmlPullParser.END_TAG){ - hogCounter++; - state = STATE_ROOT; - }else throwException(xmlPuller.getText(), eventType); - break; - } - eventType = getEventType(xmlPuller); - }//end while(eventtype != END_DOCUMENT - return team; - } catch (NumberFormatException e){ - e.printStackTrace(); - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{ - if(getEventType(xmlPuller) == XmlPullParser.TEXT){ - String txt = xmlPuller.getText(); - if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){ - return txt; - } - } - throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag); - } - - /** - * Skips whitespaces.. - */ - private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{ - int eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){ - eventType = xmlPuller.next(); - } - return eventType; - } - private static void throwException(String file, int eventType){ - throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType)); - } - - public void writeToXml(OutputStream os){ - XmlSerializer serializer = Xml.newSerializer(); - try{ - serializer.setOutput(os, "UTF-8"); - serializer.startDocument("UTF-8", true); - serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); - - serializer.startTag(null, "team"); - serializer.startTag(null, "name"); - serializer.text(name); - serializer.endTag(null, "name"); - serializer.startTag(null, "flag"); - serializer.text(flag); - serializer.endTag(null, "flag"); - serializer.startTag(null, "fort"); - serializer.text(fort); - serializer.endTag(null, "fort"); - serializer.startTag(null, "grave"); - serializer.text(grave); - serializer.endTag(null, "grave"); - serializer.startTag(null, "voice"); - serializer.text(voice); - serializer.endTag(null, "voice"); - serializer.startTag(null, "hash"); - serializer.text(hash); - serializer.endTag(null, "hash"); - - for(int i = 0; i < maxNumberOfHogs; i++){ - serializer.startTag(null, "hog"); - serializer.startTag(null, "name"); - serializer.text(hogNames[i]); - serializer.endTag(null, "name"); - serializer.startTag(null, "hat"); - serializer.text(hats[i]); - serializer.endTag(null, "hat"); - serializer.startTag(null, "level"); - serializer.text(String.valueOf(levels[i])); - serializer.endTag(null, "level"); - - serializer.endTag(null, "hog"); - } - serializer.endTag(null, "team"); - serializer.endDocument(); - serializer.flush(); - - } catch (IOException e) { - e.printStackTrace(); - }finally{ - try { - os.close(); - } catch (IOException e) {} - } + @Override + public String toString() { + return "Team [name=" + name + ", grave=" + grave + ", flag=" + flag + + ", voice=" + voice + ", fort=" + fort + ", hogs=" + hogs + + "]"; } - /* - * END XML METHODS - */ - - - - /* - * PARCABLE METHODS - */ - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeString(grave); - dest.writeString(flag); - dest.writeString(voice); - dest.writeString(fort); - dest.writeString(hash); - dest.writeStringArray(hats); - dest.writeStringArray(hogNames); - dest.writeIntArray(levels); - dest.writeInt(color); - dest.writeInt(hogCount); - dest.writeString(file); - } - - - public void readFromParcel(Parcel src){ - name = src.readString(); - grave = src.readString(); - flag = src.readString(); - voice = src.readString(); - fort = src.readString(); - hash = src.readString(); - src.readStringArray(hats); - src.readStringArray(hogNames); - src.readIntArray(levels); - color = src.readInt(); - hogCount = src.readInt(); - file = src.readString(); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Team createFromParcel(Parcel source) { - return new Team(source); - } - public Team[] newArray(int size) { - return new Team[size]; - } - - }; - - /* - * END PARCABLE METHODS - */ - } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamFile.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,18 @@ +package org.hedgewars.hedgeroid.Datastructures; + +import java.io.File; + +public final class TeamFile { + public final Team team; + public final File file; + + public TeamFile(Team team, File file) { + this.team = team; + this.file = file; + } + + @Override + public String toString() { + return "TeamFile [team=" + team + ", file=" + file + "]"; + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamInGame.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamInGame.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,15 @@ +package org.hedgewars.hedgeroid.Datastructures; + +public final class TeamInGame { + public final Team team; + public final TeamIngameAttributes ingameAttribs; + + public TeamInGame(Team team, TeamIngameAttributes ingameAttribs) { + this.team = team; + this.ingameAttribs = ingameAttribs; + } + + public TeamInGame withAttribs(TeamIngameAttributes attribs) { + return new TeamInGame(team, attribs); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamIngameAttributes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamIngameAttributes.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,61 @@ +package org.hedgewars.hedgeroid.Datastructures; + +import java.util.ArrayList; +import java.util.Random; + +public final class TeamIngameAttributes { + public static final int[] TEAM_COLORS = { + 0xd12b42, /* red */ + 0x4980c1, /* blue */ + 0x6ab530, /* green */ + 0xbc64c4, /* purple */ + 0xe76d14, /* orange */ + 0x3fb6e6, /* cyan */ + 0xe3e90c, /* yellow */ + 0x61d4ac, /* mint */ + 0xf1c3e1, /* pink */ + /* add new colors here */ + }; + + public final String ownerName; + public final int colorIndex, hogCount; + public final boolean remoteDriven; + + public TeamIngameAttributes(String ownerName, int colorIndex, int hogCount, boolean remoteDriven) { + this.ownerName = ownerName; + this.colorIndex = colorIndex; + this.hogCount = hogCount; + this.remoteDriven = remoteDriven; + } + + public static int randomColorIndex(int[] illegalColors){ + Random rnd = new Random(); + ArrayList legalcolors = new ArrayList(); + for(int i=0; i{ - +public class Weapon implements Comparable{ public static final String DIRECTORY_WEAPON = "weapons"; + public static final int maxWeapons = PascalExports.HWgetNumberOfWeapons(); private String name; private String QT; private String prob; private String delay; private String crate; - private static int maxWeapons; - - static{ - maxWeapons = PascalExports.HWgetNumberOfWeapons(); - } public Weapon(String _name, String _QT, String _prob, String _delay, String _crate){ name = _name; @@ -65,154 +45,11 @@ crate = String.format("e%s %s%s", "ammreinf", _crate, sb); } - public Weapon(Parcel in){ - readFromParcel(in); - } - public String toString(){ return name; } - - public void sendToEngine(EngineProtocolNetwork epn, int teamsCount) throws IOException{ - epn.sendToEngine(QT);//command prefix is already in string - epn.sendToEngine(prob); - epn.sendToEngine(delay); - epn.sendToEngine(crate); - for(int i = 0; i < teamsCount; i++){ - epn.sendToEngine("eammstore"); - } - } - - public static final int STATE_START = 0; - public static final int STATE_ROOT = 1; - public static final int STATE_NAME = 2; - public static final int STATE_QT = 3; - public static final int STATE_PROBABILITY = 4; - public static final int STATE_DELAY = 5; - public static final int STATE_CRATE = 6; - - public static ArrayList getWeapons(Context c) throws IllegalArgumentException{ - String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_WEAPON + '/'; - String[] files = new File(dir).list(); - if(files == null) files = new String[]{}; - - ArrayList weapons = new ArrayList(); - - try { - XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance(); - XmlPullParser xmlPuller = xmlPullFactory.newPullParser(); - - for(String file : files){ - BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024); - xmlPuller.setInput(br); - String name = null; - String qt = null; - String prob = null; - String delay = null; - String crate = null; - - int eventType = xmlPuller.getEventType(); - int state = STATE_START; - while(eventType != XmlPullParser.END_DOCUMENT){ - switch(state){ - case STATE_START: - if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("weapon")) state = STATE_ROOT; - else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType); - break; - case STATE_ROOT: - if(eventType == XmlPullParser.START_TAG){ - if(xmlPuller.getName().toLowerCase().equals("qt")) state = STATE_QT; - else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME; - else if(xmlPuller.getName().toLowerCase().equals("probability")) state = STATE_PROBABILITY; - else if(xmlPuller.getName().toLowerCase().equals("delay")) state = STATE_DELAY; - else if(xmlPuller.getName().toLowerCase().equals("crate")) state = STATE_CRATE; - else throwException(file, eventType); - }else if(eventType == XmlPullParser.END_TAG) state = STATE_START; - else throwException(xmlPuller.getText(), eventType); - break; - case STATE_NAME: - if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_QT: - if(eventType == XmlPullParser.TEXT) qt = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_PROBABILITY: - if(eventType == XmlPullParser.TEXT) prob = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_DELAY: - if(eventType == XmlPullParser.TEXT) delay = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - case STATE_CRATE: - if(eventType == XmlPullParser.TEXT) crate = xmlPuller.getText().trim(); - else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT; - else throwException(file, eventType); - break; - } - eventType = xmlPuller.next(); - while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){//Skip whitespaces - eventType = xmlPuller.next(); - } - }//end while(eventtype != END_DOCUMENT - weapons.add(new Weapon(name, qt, prob, delay, crate)); - }//end for(string file : files - return weapons; - - } catch (XmlPullParserException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return new ArrayList();//TODO handle correctly - } - - private static void throwException(String file, int eventType){ - throw new IllegalArgumentException(String.format("Xml file: %s malformed with eventType: %d.", file, eventType)); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(name); - dest.writeString(QT); - dest.writeString(prob); - dest.writeString(delay); - dest.writeString(crate); - } - - private void readFromParcel(Parcel src){ - name = src.readString(); - QT = src.readString(); - prob = src.readString(); - delay = src.readString(); - crate = src.readString(); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public Weapon createFromParcel(Parcel source) { - return new Weapon(source); - } - public Weapon[] newArray(int size) { - return new Weapon[size]; - } - - }; - public int compareTo(Weapon another) { return name.compareTo(another.name); } - - } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java Mon Aug 06 22:39:36 2012 +0200 @@ -8,6 +8,7 @@ import org.hedgewars.hedgeroid.R; import org.hedgewars.hedgeroid.Utils; import org.hedgewars.hedgeroid.Datastructures.Scheme; +import org.hedgewars.hedgeroid.Datastructures.Schemes; import org.hedgewars.hedgeroid.Datastructures.Team; import org.hedgewars.hedgeroid.Datastructures.Weapon; @@ -44,7 +45,7 @@ @Override protected Boolean doInBackground(Object... params) { try { - Utils.resRawToFilesDir(act, R.array.schemes, Scheme.DIRECTORY_SCHEME); + Utils.writeStreamToFile(act.getResources().openRawResource(R.raw.schemes_builtin), Schemes.getBuiltinSchemesFile(act)); Utils.resRawToFilesDir(act, R.array.weapons, Weapon.DIRECTORY_WEAPON); Utils.resRawToFilesDir(act, R.array.teams, Team.DIRECTORY_TEAMS); copyFileOrDir(act.getAssets(), Utils.getDataPathFile(act), "Data"); diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (c) 2011-2012 Richard Deurwaarder - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - - -package org.hedgewars.hedgeroid.EngineProtocol; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.UnknownHostException; - -public class EngineProtocolNetwork extends Thread { - - public static final String GAMEMODE_LOCAL = "TL"; - public static final String GAMEMODE_DEMO = "TD"; - public static final String GAMEMODE_NET = "TN"; - public static final String GAMEMODE_SAVE = "TS"; - - public static final int BUFFER_SIZE = 255; //From iOS code which got it from the origional frontend - - public static final int MODE_GENLANDPREVIEW = 0; - public static final int MODE_GAME = 1; - - private ServerSocket serverSocket; - private InputStream input; - private OutputStream output; - public int port; - private final GameConfig config; - private boolean clientQuit = false; - - public EngineProtocolNetwork(GameConfig _config){ - config = _config; - try { - serverSocket = new ServerSocket(0); - port = serverSocket.getLocalPort(); - Thread ipcThread = new Thread(this, "IPC - Thread"); - ipcThread.start(); - } catch (UnknownHostException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void run(){ - //if(mode == MODE_GENLANDPREVIEW) genLandPreviewIPC(); - /*else if (mode == MODE_GAME)*/ gameIPC(); - } - - private void gameIPC(){ - Socket sock = null; - try{ - sock = serverSocket.accept(); - input = sock.getInputStream(); - output = sock.getOutputStream(); - - int msgSize = 0; - byte[] buffer = new byte[BUFFER_SIZE]; - - while(!clientQuit){ - msgSize = 0; - - input.read(buffer, 0, 1); - msgSize = buffer[0]; - - input.read(buffer, 0, msgSize); - System.out.println("IPC" + (char)buffer[0] + " : " + new String(buffer, 1,msgSize-1, "US_ASCII")); - switch(buffer[0]){ - case 'C'://game init - config.sendToEngine(this); - break; - case '?'://ping - pong - sendToEngine("!"); - break; - case 'e'://Send protocol version - System.out.println(new String(buffer)); - break; - case 'i'://game statistics - switch(buffer[1]){ - case 'r'://winning team - break; - case 'D'://best shot - break; - case 'k'://best hedgehog - break; - case 'K'://# hogs killed - break; - case 'H'://team health graph - break; - case 'T':// local team stats - break; - case 'P'://teams ranking - break; - case 's'://self damage - break; - case 'S'://friendly fire - break; - case 'B'://turn skipped - break; - default: - } - break; - case 'E'://error - quits game - System.out.println(new String(buffer)); - return; - case 'q'://game ended remove save file - - return; - case 'Q'://game ended but not finished - - return; - } - - } - }catch(IOException e){ - e.printStackTrace(); - }finally{ - try { - if(sock != null) sock.close(); - } catch (IOException e) {} - try{ - if(serverSocket != null) serverSocket.close(); - } catch (IOException e) {} - } - } - - public void sendToEngine(String s){ - int length = s.length(); - - try { - output.write(length); - output.write(s.getBytes(), 0, length); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void quitIPC(){ - clientQuit = true; - } - -} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java Mon Aug 06 22:39:36 2012 +0200 @@ -18,9 +18,7 @@ package org.hedgewars.hedgeroid.EngineProtocol; -import java.io.IOException; import java.util.ArrayList; -import java.util.UUID; import org.hedgewars.hedgeroid.Datastructures.GameMode; import org.hedgewars.hedgeroid.Datastructures.Map; @@ -28,12 +26,7 @@ import org.hedgewars.hedgeroid.Datastructures.Team; import org.hedgewars.hedgeroid.Datastructures.Weapon; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -public class GameConfig implements Parcelable{ - +public class GameConfig { public GameMode mode = GameMode.MODE_LOCAL; public Map map = null; public String theme = null; @@ -49,79 +42,4 @@ public GameConfig(){ } - - public GameConfig(Parcel in){ - readFromParcel(in); - } - - - - public void sendToEngine(EngineProtocolNetwork epn) throws IOException{ - Log.d("HW_Frontend", "Sending Gameconfig..."); - int teamCount = 4; - epn.sendToEngine("TL"); //Write game mode - if(training != null) epn.sendToEngine(String.format("escript Scripts/Training/%s.lua", training)); - else if(style != null) epn.sendToEngine(String.format("escript Scripts/Multiplayer/%s.lua", style)); - - //seed info - epn.sendToEngine(String.format("eseed {%s}", UUID.randomUUID().toString())); - - map.sendToEngine(epn); - //dimensions of the map - //templatefilter_command - //mapgen_command - //mazesize_command - - epn.sendToEngine(String.format("etheme %s", theme)); - - scheme.sendToEngine(epn); - - weapon.sendToEngine(epn, teamCount); - - for(Team t : teams){ - if(t != null)t.sendToEngine(epn, teamCount, scheme.getHealth()); - } - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mode.name()); - dest.writeParcelable(map, flags); - dest.writeString(theme); - dest.writeParcelable(scheme, flags); - dest.writeParcelable(weapon, flags); - dest.writeString(style); - dest.writeString(training); - dest.writeString(seed); - dest.writeParcelableArray((Team[])teams.toArray(new Team[1]), 0); - } - - private void readFromParcel(Parcel src){ - mode = GameMode.valueOf(src.readString()); - map = src.readParcelable(Map.class.getClassLoader()); - theme = src.readString(); - scheme = src.readParcelable(Scheme.class.getClassLoader()); - weapon = src.readParcelable(Weapon.class.getClassLoader()); - style = src.readString(); - training = src.readString(); - seed = src.readString(); - Parcelable[] parcelables = src.readParcelableArray(Team[].class.getClassLoader()); - for(Parcelable team : parcelables){ - teams.add((Team)team); - } - - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public GameConfig createFromParcel(Parcel source) { - return new GameConfig(source); - } - public GameConfig[] newArray(int size) { - return new GameConfig[size]; - } - }; - } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java Mon Aug 06 22:39:36 2012 +0200 @@ -36,5 +36,5 @@ public static native int HWgetNumberOfWeapons(); public static native int HWgetMaxNumberOfTeams(); public static native int HWgetMaxNumberOfHogs(); - public static native int HWterminate(boolean b); + public static native int HWterminate(boolean b); } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java Mon Aug 06 22:39:36 2012 +0200 @@ -6,9 +6,12 @@ import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; -import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork; import org.hedgewars.hedgeroid.EngineProtocol.GameConfig; import org.hedgewars.hedgeroid.EngineProtocol.PascalExports; +import org.hedgewars.hedgeroid.frontlib.Flib; +import org.hedgewars.hedgeroid.frontlib.Frontlib.GameSetupPtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.GameconnPtr; +import org.hedgewars.hedgeroid.netplay.TickHandler; import android.app.Activity; import android.content.Context; @@ -23,6 +26,7 @@ import android.media.AudioTrack; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerThread; import android.os.Message; import android.util.DisplayMetrics; import android.util.Log; @@ -37,13 +41,19 @@ SDL Activity */ public class SDLActivity extends Activity { - + /** + * Set startConfig to the desired config when starting this activity. This avoids having to parcel all + * the config objects into the Intent. Not particularly elegant, but it's actually a recommended + * way to do this (http://developer.android.com/guide/faq/framework.html#3) + */ + public static volatile GameConfig startConfig; + // Main components public static SDLActivity mSingleton; private static SDLSurface mSurface; // This is what SDL runs in. It invokes SDL_main(), eventually - private static Thread mSDLThread; + private static Thread mSDLThread; // Guarded by SDLActivity.class // Audio private static Thread mAudioThread; @@ -74,11 +84,8 @@ mSingleton = this; // Set up the surface - GameConfig config = getIntent().getParcelableExtra("config"); - - mSurface = new SDLSurface(getApplication(), config); + mSurface = new SDLSurface(getApplication(), startConfig); setContentView(mSurface); - SurfaceHolder holder = mSurface.getHolder(); } // Events @@ -108,15 +115,15 @@ SDLActivity.nativeQuit(); // Now wait for the SDL thread to quit - if (mSDLThread != null) { - try { - mSDLThread.join(); - } catch(Exception e) { - Log.v("SDL", "Problem stopping thread: " + e); + synchronized(SDLActivity.class) { + if (mSDLThread != null) { + try { + mSDLThread.join(); + } catch(Exception e) { + Log.w("SDL", "Problem stopping thread: " + e); + } + mSDLThread = null; } - mSDLThread = null; - - //Log.v("SDL", "Finished waiting for SDL thread"); } } @@ -175,13 +182,14 @@ } public static void startApp(int width, int height, GameConfig config) { - // Start up the C app thread - if (mSDLThread == null) { - mSDLThread = new Thread(new SDLMain(width, height, config), "SDLThread"); - mSDLThread.start(); - } - else { - SDLActivity.nativeResume(); + synchronized(SDLActivity.class) { + // Start up the C app thread + if (mSDLThread == null) { + mSDLThread = new Thread(new SDLMain(width, height, config), "SDLThread"); + mSDLThread.start(); + } else { + SDLActivity.nativeResume(); + } } } @@ -425,23 +433,34 @@ public void run() { //Set up the IPC socket server to communicate with the engine - EngineProtocolNetwork ipc = new EngineProtocolNetwork(config); + HandlerThread thread = new HandlerThread("IPC thread"); + thread.start(); // TODO ensure it gets stopped + final GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create("Xeli", GameSetupPtr.createJavaOwned(config), false); + if(conn == null) { + throw new AssertionError(); + } + int port = Flib.INSTANCE.flib_gameconn_getport(conn); String path = Utils.getDataPath(SDLActivity.mSingleton);//This represents the data directory path = path.substring(0, path.length()-1);//remove the trailing '/' - // Runs SDL_main() with added parameters - SDLActivity.nativeInit(new String[] { String.valueOf(ipc.port), + SDLActivity.nativeInit(new String[] { String.valueOf(port), String.valueOf(surfaceWidth), String.valueOf(surfaceHeight), "0", "en.txt", "xeli", "1", "1", "1", path, "" }); + new TickHandler(thread.getLooper(), 50, new Runnable() { + public void run() { + Flib.INSTANCE.flib_gameconn_tick(conn); + } + }); try { - ipc.quitIPC(); - ipc.join(); + thread.quit(); + thread.join(); } catch (InterruptedException e) { - e.printStackTrace(); + throw new AssertionError(); } + Flib.INSTANCE.flib_gameconn_destroy(conn); Log.v("SDL", "SDL thread terminated"); } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java Mon Aug 06 22:39:36 2012 +0200 @@ -45,7 +45,7 @@ public class StartGameActivity extends Activity { public static final int ACTIVITY_TEAM_SELECTOR = 0; - + private GameConfig config = null; private ImageButton start, back, team; private Spinner maps, gameplay, gamescheme, weapons, themes; @@ -53,8 +53,6 @@ public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); - - Scheme.parseConfiguration(this); config = new GameConfig(); setContentView(R.layout.starting_game); @@ -132,7 +130,7 @@ private void startTeamsActivity(){ Intent i = new Intent(StartGameActivity.this, TeamSelectionActivity.class); - i.putParcelableArrayListExtra("teams", config.teams); + // TODO i.putParcelableArrayListExtra("teams", config.teams); startActivityForResult(i, ACTIVITY_TEAM_SELECTOR); } @@ -143,7 +141,7 @@ Parcelable[] parcelables = (Parcelable[])data.getParcelableArrayExtra("teams"); config.teams.clear(); for(Parcelable t : parcelables){ - config.teams.add((Team)t); + // TODO config.teams.add((Team)t); } teamCount.getDrawable().setLevel(config.teams.size()); } @@ -209,11 +207,11 @@ if(config.teams.size() < 2){ Toast.makeText(StartGameActivity.this, R.string.not_enough_teams, Toast.LENGTH_LONG).show(); startTeamsActivity(); - } - else{ + } else { + SDLActivity.startConfig = config; Intent i = new Intent(StartGameActivity.this, SDLActivity.class); - i.putExtra("config", config); - startActivity(i);} + startActivity(i); + } } }; diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java Mon Aug 06 22:39:36 2012 +0200 @@ -20,14 +20,14 @@ package org.hedgewars.hedgeroid; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils; +import org.hedgewars.hedgeroid.Datastructures.Hog; import org.hedgewars.hedgeroid.Datastructures.Team; import android.app.Activity; @@ -247,22 +247,12 @@ private OnClickListener saveClicker = new OnClickListener() { public void onClick(View v) { - Toast.makeText(TeamCreatorActivity.this, R.string.saved, Toast.LENGTH_SHORT).show(); - saved = true; - Team team = new Team(); - team.name = name.getText().toString(); - HashMap hashmap = (HashMap) flag.getSelectedItem(); - - team.flag = (String) hashmap.get("txt"); - team.fort = fort.getSelectedItem().toString(); - hashmap = (HashMap) grave.getSelectedItem(); - team.grave = hashmap.get("txt").toString(); - team.hash = "0"; - team.voice = voice.getSelectedItem().toString(); - team.file = fileName; - - hashmap = ((HashMap) difficulty.getSelectedItem()); - String levelString = hashmap.get("txt").toString(); + String teamName = name.getText().toString(); + String teamFlag = (String)((Map) flag.getSelectedItem()).get("txt"); + String teamFort = fort.getSelectedItem().toString(); + String teamGrave = (String)((Map) grave.getSelectedItem()).get("txt"); + String teamVoice = voice.getSelectedItem().toString(); + String levelString = (String)((Map) difficulty.getSelectedItem()).get("txt"); int levelInt; if (levelString.equals(getString(R.string.human))) { levelInt = 0; @@ -277,28 +267,39 @@ } else { levelInt = 5; } - + + List hogs = new ArrayList(); for (int i = 0; i < hogName.size(); i++) { - team.hogNames[i] = hogName.get(i).getText().toString(); - hashmap = (HashMap) hogHat.get(i).getSelectedItem(); - team.hats[i] = hashmap.get("txt").toString(); - team.levels[i] = levelInt; + String name = hogName.get(i).getText().toString(); + String hat = ((Map) hogHat.get(i).getSelectedItem()).get("txt").toString(); + hogs.add(new Hog(name, hat, levelInt)); + } + + Team team = new Team(teamName, teamGrave, teamFlag, teamVoice, teamFort, hogs); + File teamsDir = new File(getFilesDir(), Team.DIRECTORY_TEAMS); + if (!teamsDir.exists()) teamsDir.mkdir(); + if(fileName == null){ + fileName = createNewFilename(Utils.replaceBadChars(team.name)); } try { - File teamsDir = new File(getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS); - if (!teamsDir.exists()) teamsDir.mkdir(); - if(team.file == null){ - team.setFileName(TeamCreatorActivity.this); - } - FileOutputStream fos = new FileOutputStream(String.format("%s/%s", teamsDir.getAbsolutePath(), team.file)); - team.writeToXml(fos); - } catch (FileNotFoundException e) { - e.printStackTrace(); + team.save(new File(teamsDir, fileName)); + Toast.makeText(TeamCreatorActivity.this, R.string.saved, Toast.LENGTH_SHORT).show(); + saved = true; + } catch(IOException e) { + Toast.makeText(getApplicationContext(), R.string.error_save_failed, Toast.LENGTH_SHORT).show(); } } - }; + private String createNewFilename(String suggestedName){ + File f = new File(getFilesDir(), suggestedName); + if(f.exists()){ + return createNewFilename(suggestedName + (int)(Math.random()*10)); + } else { + return suggestedName + (int)(Math.random()*10); + } + } + private OnItemSelectedListener fortSelector = new OnItemSelectedListener() { public void onItemSelected(AdapterView arg0, View arg1, int position, long arg3) { @@ -362,7 +363,7 @@ position = 0; for (HashMap hashmap : typesData) { - if (hashmap.get("txt").equals(t.levels[0])) { + if (t.hogs.get(0) != null && hashmap.get("txt").equals(t.hogs.get(0).level)) { difficulty.setSelection(position); break; } @@ -387,14 +388,14 @@ for (int i = 0; i < Team.maxNumberOfHogs; i++) { position = 0; for (HashMap hashmap : hatsData) { - if (hashmap.get("txt").equals(t.hats[i])) { + if (hashmap.get("txt").equals(t.hogs.get(i).hat)) { hogHat.get(i).setSelection(position); } } - hogName.get(i).setText(t.hogNames[i]); + hogName.get(i).setText(t.hogs.get(i).name); } - this.fileName = t.file; + //this.fileName = t.file; } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java Mon Aug 06 22:39:36 2012 +0200 @@ -26,11 +26,16 @@ import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils; import org.hedgewars.hedgeroid.Datastructures.Team; +import org.hedgewars.hedgeroid.Datastructures.TeamFile; +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; +import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; +import android.util.Pair; import android.view.ContextMenu; import android.view.MenuItem; import android.view.View; @@ -47,8 +52,10 @@ import android.widget.TextView; public class TeamSelectionActivity extends Activity implements Runnable{ - private static final int ACTIVITY_TEAMCREATION = 0; + + private static volatile List> activityParams; + private static volatile List> activityReturn; private ImageButton addTeam, back; private ListView availableTeams, selectedTeams; @@ -86,14 +93,14 @@ } public void run(){ - List> teamsList = FrontendDataUtils.getTeams(this);//teams from xml - ArrayList teamsStartGame = getIntent().getParcelableArrayListExtra("teams");//possible selected teams + List> teamsList = getTeams(this);//teams from xml + ArrayList teamsStartGame = getIntent().getStringArrayListExtra("selectedTeamNames"); for(HashMap hashmap : teamsList){ boolean added = false; - for(Team t : teamsStartGame){ - if(((Team)hashmap.get("team")).equals(t)){//add to available or add to selected - selectedTeamsList.add(FrontendDataUtils.teamToMap(t));//create a new hashmap to ensure all variables are entered into the map + for(String teamName : teamsStartGame){ + if(((Team)hashmap.get("team")).name.equals(teamName)){ // add to available or add to selected + selectedTeamsList.add(hashmap); added = true; break; } @@ -139,7 +146,7 @@ */ private void updateListViews(){ unregisterForContextMenu(availableTeams); - availableTeamsList = FrontendDataUtils.getTeams(this); + availableTeamsList = getTeams(this); ArrayList> toBeRemoved = new ArrayList>(); for(HashMap hashmap : selectedTeamsList){ String name = (String)hashmap.get("txt"); @@ -253,21 +260,19 @@ public boolean onContextItemSelected(MenuItem item){ AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo(); int position = menuInfo.position; + TeamFile teamfile = (TeamFile)availableTeamsList.get(position).get("teamfile"); switch(item.getItemId()){ case 0://select selectAvailableTeamsItem(position); return true; case 1://delete - Team team = (Team)availableTeamsList.get(position).get("team"); - File f = new File(String.format("%s/%s/%s", TeamSelectionActivity.this.getFilesDir(), Team.DIRECTORY_TEAMS, team.file)); - f.delete(); + teamfile.file.delete(); availableTeamsList.remove(position); ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged(); return true; case 2://edit Intent i = new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class); - Team t = (Team)availableTeamsList.get(position).get("team"); - i.putExtra("team", t); + i.putExtra("teamfile", teamfile.file); startActivityForResult(i, ACTIVITY_TEAMCREATION); return true; } @@ -304,4 +309,36 @@ setResult(Activity.RESULT_OK, i); } + + private static List> getTeams(Context c){ + List> ret = new ArrayList>(); + List teamfiles = FrontendDataUtils.getTeamFiles(c); + for(TeamFile tf : teamfiles) { + ret.add(teamfileToMap(tf)); + } + return ret; + } + + private static final int[] botlevelDrawables = new int[] { + R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1 + }; + + private static HashMap teamfileToMap(TeamFile tf){ + HashMap hashmap = new HashMap(); + Team t = tf.team; + hashmap.put("team", t); + hashmap.put("teamfile", tf); + hashmap.put("txt", t.name); + hashmap.put("color", t.color); + hashmap.put("count", t.hogCount); + + int botlevel = t.hogs.get(0).level; + if(botlevel<0 || botlevel>=botlevelDrawables.length) { + hashmap.put("img", R.drawable.bot1); + } else { + hashmap.put("img", botlevelDrawables[botlevel]); + } + return hashmap; + return null; + } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java Mon Aug 06 22:39:36 2012 +0200 @@ -270,4 +270,24 @@ closeQuietly(is); } } + + private static final char[] badFilenameChars = new char[] { '/', '\\', ':', '*', '?', '\"', '<', '>', '|', '.', '\0' }; + + /** + * Modify the given String so that it can be used as part of a filename + * without causing problems from illegal/special characters. + * + * The result should be similar to the input, but isn't necessarily + * reversible. + */ + public static String replaceBadChars(String name) { + if (name == null || name.trim().length()==0) { + return "_"; + } + name = name.trim(); + for (char badChar : badFilenameChars) { + name = name.replace(badChar, '_'); + } + return name; + } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,35 @@ +package org.hedgewars.hedgeroid.frontlib; + +import java.util.Collections; + +import android.util.Log; + +import com.sun.jna.Library; +import com.sun.jna.Native; + +public class Flib { + static { + System.loadLibrary("SDL_net"); + System.setProperty("jna.encoding", "UTF8"); // Ugly global setting, but it seems JNA doesn't allow setting this per-library... + } + public static final Frontlib INSTANCE = (Frontlib)Native.loadLibrary("frontlib", Frontlib.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, FrontlibTypeMapper.INSTANCE)); + + // Hook frontlib logging into Android logging + private static final Frontlib.LogCallback logCb = new Frontlib.LogCallback() { + public void callback(int level, String message) { + if(level >= Frontlib.FLIB_LOGLEVEL_ERROR) { + Log.e("Frontlib", message); + } else if(level == Frontlib.FLIB_LOGLEVEL_WARNING){ + Log.w("Frontlib", message); + } else if(level == Frontlib.FLIB_LOGLEVEL_INFO){ + Log.i("Frontlib", message); + } else if(level <= Frontlib.FLIB_LOGLEVEL_DEBUG){ + Log.d("Frontlib", message); + } + } + }; + static { + INSTANCE.flib_log_setLevel(Frontlib.FLIB_LOGLEVEL_ALL); + INSTANCE.flib_log_setCallback(logCb); + } +} \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,793 @@ +package org.hedgewars.hedgeroid.frontlib; +import java.nio.Buffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hedgewars.hedgeroid.Datastructures.Hog; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting; +import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom; +import org.hedgewars.hedgeroid.Datastructures.Scheme; +import org.hedgewars.hedgeroid.Datastructures.Team; +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; +import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; +import org.hedgewars.hedgeroid.EngineProtocol.GameConfig; + +import com.sun.jna.Callback; +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.NativeLong; +import com.sun.jna.Pointer; +import com.sun.jna.PointerType; +import com.sun.jna.Structure; + +public interface Frontlib extends Library { + static final int NATIVE_INT_SIZE = 4; + static final int NATIVE_BOOL_SIZE = 1; + + static final int NETCONN_STATE_CONNECTING = 0; + static final int NETCONN_STATE_LOBBY = 1; + static final int NETCONN_STATE_ROOM = 2; + static final int NETCONN_STATE_INGAME = 3; + static final int NETCONN_STATE_DISCONNECTED = 10; + + static final int NETCONN_DISCONNECT_NORMAL = 0; + static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1; + static final int NETCONN_DISCONNECT_AUTH_FAILED = 2; + static final int NETCONN_DISCONNECT_CONNLOST = 3; + static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100; + + static final int NETCONN_ROOMLEAVE_ABANDONED = 0; + static final int NETCONN_ROOMLEAVE_KICKED = 1; + + static final int NETCONN_MSG_TYPE_PLAYERINFO = 0; + static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1; + static final int NETCONN_MSG_TYPE_WARNING = 2; + static final int NETCONN_MSG_TYPE_ERROR = 3; + + static final int NETCONN_MAPCHANGE_FULL = 0; + static final int NETCONN_MAPCHANGE_MAP = 1; + static final int NETCONN_MAPCHANGE_MAPGEN = 2; + static final int NETCONN_MAPCHANGE_DRAWNMAP = 3; + static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4; + static final int NETCONN_MAPCHANGE_TEMPLATE = 5; + static final int NETCONN_MAPCHANGE_THEME = 6; + static final int NETCONN_MAPCHANGE_SEED = 7; + + static final int GAME_END_FINISHED = 0; + static final int GAME_END_INTERRUPTED = 1; + static final int GAME_END_HALTED = 2; + static final int GAME_END_ERROR = 3; + + static final int HEDGEHOGS_PER_TEAM = 8; + + public static class NetconnPtr extends PointerType { } + public static class MapconnPtr extends PointerType { } + public static class GameconnPtr extends PointerType { } + public static class MetaschemePtr extends PointerType { } + + public static class RoomArrayPtr extends PointerType { + /** + * Returns the (native-owned) rooms in this list + */ + public RoomlistRoom[] getRooms(int count) { + Pointer ptr = getPointer(); + if(ptr == null) { + return new RoomlistRoom[0]; + } + Pointer[] untypedPtrs = ptr.getPointerArray(0, count); + RoomlistRoom[] result = new RoomlistRoom[count]; + for(int i=0; i hogs = new ArrayList(); + for(int i=0; i deref() { + return deref(getPointer()); + } + + public static List deref(Pointer p) { + SchemelistStruct sls = new SchemelistStruct(p); + sls.read(); + return sls.toSchemeList(); + } + + public static SchemelistPtr createJavaOwned(List schemes) { + SchemelistPtr result = new SchemelistPtr(); + result.javaOwnedInstance = new SchemelistStruct(); + result.javaOwnedInstance.fillFrom(schemes); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class GameSetupPtr extends PointerType { + public static GameSetupPtr createJavaOwned(GameConfig conf) { + GameSetupStruct gss = GameSetupStruct.from(conf); + gss.write(); + GameSetupPtr result = new GameSetupPtr(); + result.setPointer(gss.getPointer()); + return result; + } + } + + static class HogStruct extends Structure { + public static class ByVal extends HogStruct implements Structure.ByValue {} + public static class ByRef extends HogStruct implements Structure.ByReference {} + private static String[] FIELD_ORDER = new String[] {"name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"}; + + public HogStruct() { super(); setFieldOrder(FIELD_ORDER); } + public HogStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); } + + public static HogStruct from(Hog hog) { + HogStruct hs = new HogStruct(); + hs.difficulty = hog.level; + hs.hat = hog.hat; + hs.name = hog.name; + // TODO weaponset + // TODO initialHealth + return hs; + } + + public String name; + public String hat; + + public int rounds; + public int kills; + public int deaths; + public int suicides; + + public int difficulty; + + public int initialHealth; + public WeaponsetPtr weaponset; + } + + static class TeamStruct extends Structure { + public static class ByVal extends TeamStruct implements Structure.ByValue {} + public static class ByRef extends TeamStruct implements Structure.ByReference {} + private static String[] FIELD_ORDER = new String[] {"hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"}; + + public TeamStruct() { super(); setFieldOrder(FIELD_ORDER); } + public TeamStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); } + + public static TeamStruct from(Team team, TeamIngameAttributes attrs) { + TeamStruct ts = new TeamStruct(); + if(team != null) { + ts.name = team.name; + ts.grave = team.grave; + ts.flag = team.flag; + ts.voicepack = team.voice; + ts.fort = team.fort; + if(team.hogs.size() != HEDGEHOGS_PER_TEAM) { + throw new IllegalArgumentException(); + } + for(int i=0; i settingList = new ArrayList(settingCount); + List modList = new ArrayList(modCount); + + Structure[] settingStructs = settings.toArray(settingCount); + Structure[] modStructs = mods.toArray(modCount); + + for(int i=0; i settingsMap = new HashMap(); + for(int i=0; i modsMap = new HashMap(); + for(int i=0; i toSchemeList() { + if(schemeCount<=0) { + return new ArrayList(); + } else { + List schemeList = new ArrayList(schemeCount); + + Structure[] schemePtrStructs = schemes.toArray(schemeCount); + + for(int i=0; i schemeList) { + schemeCount = schemeList.size(); + schemes = new SchemePointerByReference(); + Structure[] schemePtrStructs = schemes.toArray(schemeCount); + + for(int i=0; i nativeType() { + return Byte.class; + } + public Object fromNative(Object value, FromNativeContext context) { + return ((Byte)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE; + } + public Object toNative(Object value, ToNativeContext context) { + return Byte.valueOf((byte)(Boolean.TRUE.equals(value) ? 1 : 0)); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/FrontlibTypeMapper.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/FrontlibTypeMapper.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; - -import java.io.UnsupportedEncodingException; - -import com.sun.jna.DefaultTypeMapper; -import com.sun.jna.FromNativeContext; -import com.sun.jna.FromNativeConverter; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.ToNativeContext; -import com.sun.jna.ToNativeConverter; -import com.sun.jna.TypeConverter; -import com.sun.jna.TypeMapper; - -public class FrontlibTypeMapper extends DefaultTypeMapper { - public static final TypeMapper INSTANCE = new FrontlibTypeMapper(); - - protected FrontlibTypeMapper() { - addTypeConverter(Boolean.class, new BooleanConverter()); - addToNativeConverter(String.class, new StringToNativeConverter()); - addFromNativeConverter(String.class, new StringFromNativeConverter()); - } -} - -class BooleanConverter implements TypeConverter { - public Class nativeType() { - return Byte.class; - } - public Object fromNative(Object value, FromNativeContext context) { - return ((Byte)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE; - } - public Object toNative(Object value, ToNativeContext context) { - return Byte.valueOf((byte)(Boolean.TRUE.equals(value) ? 1 : 0)); - } -} - -class StringToNativeConverter implements ToNativeConverter { - public byte[] toNative(Object value, ToNativeContext context) { - try { - return value==null ? null : Native.toByteArray((String)value, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); // Never happens - } - } - - public Class nativeType() { - return byte[].class; - } -} - -class StringFromNativeConverter implements FromNativeConverter { - public String fromNative(Object value, FromNativeContext context) { - Pointer p = (Pointer)value; - if(p==null) { - return null; - } - int i=0; - while(p.getByte(i) != 0) { - i++; - } - try { - return new String(p.getByteArray(0, i), "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); // Never happens - } - } - - public Class nativeType() { - return Pointer.class; - } -} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/JnaFrontlib.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/JnaFrontlib.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,371 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; -import java.nio.Buffer; -import java.util.Collections; - -import android.util.Log; - -import com.sun.jna.Callback; -import com.sun.jna.Library; -import com.sun.jna.Native; -import com.sun.jna.NativeLong; -import com.sun.jna.Pointer; -import com.sun.jna.PointerType; -import com.sun.jna.Structure; - -class Flib { - static { - System.loadLibrary("SDL_net"); - } - public static final JnaFrontlib INSTANCE = (JnaFrontlib)Native.loadLibrary("frontlib", JnaFrontlib.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, FrontlibTypeMapper.INSTANCE)); - - // Hook frontlib logging into Android logging - private static final JnaFrontlib.LogCallback logCb = new JnaFrontlib.LogCallback() { - public void callback(int level, String message) { - if(level >= JnaFrontlib.FLIB_LOGLEVEL_ERROR) { - Log.e("Frontlib", message); - } else if(level == JnaFrontlib.FLIB_LOGLEVEL_WARNING){ - Log.w("Frontlib", message); - } else if(level == JnaFrontlib.FLIB_LOGLEVEL_INFO){ - Log.i("Frontlib", message); - } else if(level <= JnaFrontlib.FLIB_LOGLEVEL_DEBUG){ - Log.d("Frontlib", message); - } - } - }; - static { - INSTANCE.flib_log_setLevel(JnaFrontlib.FLIB_LOGLEVEL_WARNING); - INSTANCE.flib_log_setCallback(logCb); - } -} - -public interface JnaFrontlib extends Library { - static final int NETCONN_STATE_CONNECTING = 0; - static final int NETCONN_STATE_LOBBY = 1; - static final int NETCONN_STATE_ROOM = 2; - static final int NETCONN_STATE_INGAME = 3; - static final int NETCONN_STATE_DISCONNECTED = 10; - - static final int NETCONN_DISCONNECT_NORMAL = 0; - static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1; - static final int NETCONN_DISCONNECT_AUTH_FAILED = 2; - static final int NETCONN_DISCONNECT_CONNLOST = 3; - static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100; - - static final int NETCONN_ROOMLEAVE_ABANDONED = 0; - static final int NETCONN_ROOMLEAVE_KICKED = 1; - - static final int NETCONN_MSG_TYPE_PLAYERINFO = 0; - static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1; - static final int NETCONN_MSG_TYPE_WARNING = 2; - static final int NETCONN_MSG_TYPE_ERROR = 3; - - static final int NETCONN_MAPCHANGE_FULL = 0; - static final int NETCONN_MAPCHANGE_MAP = 1; - static final int NETCONN_MAPCHANGE_MAPGEN = 2; - static final int NETCONN_MAPCHANGE_DRAWNMAP = 3; - static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4; - static final int NETCONN_MAPCHANGE_TEMPLATE = 5; - static final int NETCONN_MAPCHANGE_THEME = 6; - static final int NETCONN_MAPCHANGE_SEED = 7; - - static final int GAME_END_FINISHED = 0; - static final int GAME_END_INTERRUPTED = 1; - static final int GAME_END_HALTED = 2; - static final int GAME_END_ERROR = 3; - - static class NetconnPtr extends PointerType { } - static class MapconnPtr extends PointerType { } - static class GameconnPtr extends PointerType { } - static class MetaschemePtr extends PointerType { } - - static class RoomArrayPtr extends PointerType { - /** - * Returns the (native-owned) rooms in this list - */ - public Room[] getRooms(int count) { - Pointer ptr = getPointer(); - if(ptr == null) { - return new Room[0]; - } - Pointer[] untypedPtrs = ptr.getPointerArray(0, count); - Room[] result = new Room[count]; - for(int i=0; i> { + private long nextId = 1; + + public void addPlayerWithNewId(String name) { + put(name, Pair.create(new Player(name), nextId++)); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/LobbyPlayerlistAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/LobbyPlayerlistAdapter.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,58 @@ +package org.hedgewars.hedgeroid.netplay; + +import java.util.Comparator; + +import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.Datastructures.Player; + +import android.content.Context; +import android.util.Pair; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +public class LobbyPlayerlistAdapter extends ObservableTreeMapAdapter> { + private Context context; + + public LobbyPlayerlistAdapter(Context context) { + this.context = context; + } + + @Override + protected Comparator> getEntryOrder() { + return AlphabeticalOrderComparator.INSTANCE; + } + + public Player getItem(int position) { + return getEntries().get(position).first; + } + + public long getItemId(int position) { + return getEntries().get(position).second; + } + + public boolean hasStableIds() { + return true; + } + + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(context); + v = vi.inflate(R.layout.listview_player, null); + } + + String player = getItem(position).name; + TextView username = (TextView) v.findViewById(android.R.id.text1); + username.setText(player); + return v; + } + + private static final class AlphabeticalOrderComparator implements Comparator> { + public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator(); + public int compare(Pair lhs, Pair rhs) { + return lhs.first.name.compareToIgnoreCase(rhs.first.name); + }; + } +} \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/LobbyPlayerlistFragment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/LobbyPlayerlistFragment.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,74 @@ +package org.hedgewars.hedgeroid.netplay; + +import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.Datastructures.Player; + +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView.AdapterContextMenuInfo; + +public class LobbyPlayerlistFragment extends ListFragment { + private Netplay netplay; + private LobbyPlayerlistAdapter adapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new LobbyPlayerlistAdapter(getActivity()); + adapter.setSource(netplay.lobbyPlayerlist); + setListAdapter(adapter); + } + + @Override + public void onDestroy() { + super.onDestroy(); + adapter.invalidate(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + registerForContextMenu(getListView()); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; + MenuInflater inflater = getActivity().getMenuInflater(); + inflater.inflate(R.menu.lobby_playerlist_context, menu); + menu.setHeaderIcon(R.drawable.human); + menu.setHeaderTitle(adapter.getItem(info.position).name); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); + Player player = adapter.getItem(info.position); + switch(item.getItemId()) { + case R.id.player_info: + netplay.sendPlayerInfoQuery(player.name); + return true; + case R.id.player_follow: + netplay.sendFollowPlayer(player.name); + return true; + default: + return super.onContextItemSelected(item); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_playerlist, container, false); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java Mon Aug 06 22:39:36 2012 +0200 @@ -7,6 +7,7 @@ import java.util.List; import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.frontlib.Frontlib; import android.content.Context; import android.graphics.Color; @@ -105,17 +106,17 @@ void appendMessage(int type, String msg) { switch(type) { - case JnaFrontlib.NETCONN_MSG_TYPE_ERROR: + case Frontlib.NETCONN_MSG_TYPE_ERROR: append(withColor("***"+msg, ERROR_COLOR)); break; - case JnaFrontlib.NETCONN_MSG_TYPE_WARNING: + case Frontlib.NETCONN_MSG_TYPE_WARNING: append(withColor("***"+msg, WARN_COLOR)); break; - case JnaFrontlib.NETCONN_MSG_TYPE_PLAYERINFO: + case Frontlib.NETCONN_MSG_TYPE_PLAYERINFO: // TODO Display in popup? append(withColor(msg.replace("\n", " "), PLAYERINFO_COLOR)); break; - case JnaFrontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: + case Frontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n"), new RelativeSizeSpan(1.5f))); break; default: diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java Mon Aug 06 22:39:36 2012 +0200 @@ -5,19 +5,29 @@ import org.hedgewars.hedgeroid.R; import org.hedgewars.hedgeroid.Utils; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.BoolCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.IntStrCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.MetaschemePtr; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.NetconnPtr; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomArrayPtr; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomListCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomPtr; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrRoomCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrStrCallback; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.VoidCallback; +import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom; +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; +import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; +import org.hedgewars.hedgeroid.frontlib.Flib; +import org.hedgewars.hedgeroid.frontlib.Frontlib; +import org.hedgewars.hedgeroid.frontlib.Frontlib.BoolCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.IntStrCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.MetaschemePtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.NetconnPtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomArrayPtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomListCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomPtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.StrBoolCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.StrCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.StrIntCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.StrRoomCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.StrStrCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.TeamCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.TeamPtr; +import org.hedgewars.hedgeroid.frontlib.Frontlib.VoidCallback; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -58,31 +68,32 @@ private final LocalBroadcastManager broadcastManager; private final FromNetHandler fromNetHandler = new FromNetHandler(); - private State state; + private State state = State.NOT_CONNECTED; private int foregroundUsers = 0; // Reference counter of clients requesting foreground tick speed (fast ticks) private boolean chief; // Do we control the current room? + private String playerName; // null if there is no running connection (==state is NOT_CONNECTED) private ThreadedNetConnection connection; - public final Playerlist playerList = new Playerlist(); + public final LobbyPlayerlist lobbyPlayerlist = new LobbyPlayerlist(); + public final RoomPlayerlist roomPlayerlist = new RoomPlayerlist(); public final Roomlist roomList = new Roomlist(); public final MessageLog lobbyChatlog; public final MessageLog roomChatlog; + public final Teamlist roomTeamlist = new Teamlist(); public Netplay(Context appContext) { this.appContext = appContext; broadcastManager = LocalBroadcastManager.getInstance(appContext); lobbyChatlog = new MessageLog(appContext); roomChatlog = new MessageLog(appContext); - state = State.NOT_CONNECTED; } private void clearState() { - playerList.clear(); + lobbyPlayerlist.clear(); roomList.clear(); lobbyChatlog.clear(); - roomChatlog.clear(); } public void connectToDefaultServer(String playerName) { @@ -97,6 +108,7 @@ * will change back to NOT_CONNECTED and an ACTION_DISCONNECTED broadcast is sent. */ public void connect(String name, String host, int port) { + playerName = name; if(state != State.NOT_CONNECTED) { throw new IllegalStateException("Attempt to start a new connection while the old one was still running."); } @@ -107,7 +119,10 @@ connection.setFastTickRate(foregroundUsers > 0); } - public void sendNick(String nick) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_NICK, nick); } + public void sendNick(String nick) { + playerName = nick; + sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_NICK, nick); + } public void sendPassword(String password) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_PASSWORD, password); } public void sendQuit(String message) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_QUIT, message); } public void sendRoomlistRequest() { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_ROOMLIST_REQUEST); } @@ -117,6 +132,7 @@ public void sendJoinRoom(String name) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_JOIN_ROOM, name); } public void sendCreateRoom(String name) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_CREATE_ROOM, name); } public void sendLeaveRoom(String message) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_LEAVE_ROOM, message); } + public void sendKick(String player) { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_SEND_KICK, player); } public void disconnect() { sendToNet(ThreadedNetConnection.ToNetHandler.MSG_DISCONNECT, "User Quit"); } @@ -155,6 +171,10 @@ return chief; } + public String getPlayerName() { + return playerName; + } + /** * Indicate that you want network messages to be checked regularly (several times per second). * As long as nobody requests fast ticks, the network is only checked once every few seconds @@ -210,6 +230,7 @@ /** * Processes messages from the networking system. Always runs on the main thread. */ + @SuppressLint("HandlerLeak") final class FromNetHandler extends Handler { public static final int MSG_LOBBY_JOIN = 0; public static final int MSG_LOBBY_LEAVE = 1; @@ -226,6 +247,12 @@ public static final int MSG_PASSWORD_REQUEST = 12; public static final int MSG_ENTER_ROOM_FROM_LOBBY = 13; public static final int MSG_LEAVE_ROOM = 14; + public static final int MSG_READYSTATE = 15; + public static final int MSG_TEAM_ADDED = 16; + public static final int MSG_TEAM_DELETED = 17; + public static final int MSG_TEAM_ACCEPTED = 18; + public static final int MSG_TEAM_COLOR_CHANGED = 19; + public static final int MSG_HOG_COUNT_CHANGED = 20; public FromNetHandler() { super(Looper.getMainLooper()); @@ -237,25 +264,25 @@ switch(msg.what) { case MSG_LOBBY_JOIN: { String name = (String)msg.obj; - playerList.addPlayerWithNewId(name); + lobbyPlayerlist.addPlayerWithNewId(name); lobbyChatlog.appendPlayerJoin(name); break; } case MSG_LOBBY_LEAVE: { Pair args = (Pair)msg.obj; - playerList.removePlayer(args.first); + lobbyPlayerlist.remove(args.first); lobbyChatlog.appendPlayerLeave(args.first, args.second); break; } case MSG_ROOM_JOIN: { String name = (String)msg.obj; - // TODO roomPlayerList.addPlayerWithNewId(name); + roomPlayerlist.addPlayerWithNewId(name); roomChatlog.appendPlayerJoin(name); break; } case MSG_ROOM_LEAVE: { Pair args = (Pair)msg.obj; - // TODO roomPlayerList.removePlayer(args.first); + roomPlayerlist.remove(args.first); roomChatlog.appendPlayerLeave(args.first, args.second); break; } @@ -269,23 +296,24 @@ break; } case MSG_ROOM_ADD: { - roomList.addRoomWithNewId((Room)msg.obj); + roomList.addRoomWithNewId((RoomlistRoom)msg.obj); break; } case MSG_ROOM_UPDATE: { - Pair args = (Pair)msg.obj; + Pair args = (Pair)msg.obj; roomList.updateRoom(args.first, args.second); break; } case MSG_ROOM_DELETE: { - roomList.removeRoom((String)msg.obj); + roomList.remove((String)msg.obj); break; } case MSG_ROOMLIST: { - roomList.updateList((Room[])msg.obj); + roomList.updateList((RoomlistRoom[])msg.obj); break; } case MSG_CONNECTED: { + playerName = (String)msg.obj; changeState(State.LOBBY); broadcastManager.sendBroadcast(new Intent(ACTION_CONNECTED)); break; @@ -308,6 +336,8 @@ } case MSG_ENTER_ROOM_FROM_LOBBY: { roomChatlog.clear(); + roomPlayerlist.clear(); + roomTeamlist.clear(); changeState(State.ROOM); chief = (Boolean)msg.obj; Intent intent = new Intent(ACTION_ENTERED_ROOM_FROM_LOBBY); @@ -322,6 +352,45 @@ broadcastManager.sendBroadcastSync(intent); break; } + case MSG_READYSTATE: { + Pair args = (Pair)msg.obj; + roomPlayerlist.setReady(args.first, args.second); + break; + } + case MSG_TEAM_ADDED: { + roomTeamlist.addTeamWithNewId((TeamInGame)msg.obj); + break; + } + case MSG_TEAM_DELETED: { + roomTeamlist.remove((String)msg.obj); + break; + } + case MSG_TEAM_ACCEPTED: { + // TODO depends: adding teams + break; + } + case MSG_TEAM_COLOR_CHANGED: { + Pair oldEntry = roomTeamlist.get((String)msg.obj); + if(oldEntry != null) { + TeamInGame tig = oldEntry.first; + TeamIngameAttributes tiga = tig.ingameAttribs.withColorIndex(msg.arg1); + roomTeamlist.put(tig.team.name, Pair.create(tig.withAttribs(tiga), oldEntry.second)); + } else { + Log.e("Netplay", "Color update for unknown team "+msg.obj); + } + break; + } + case MSG_HOG_COUNT_CHANGED: { + Pair oldEntry = roomTeamlist.get((String)msg.obj); + if(oldEntry != null) { + TeamInGame tig = oldEntry.first; + TeamIngameAttributes tiga = tig.ingameAttribs.withHogCount(msg.arg1); + roomTeamlist.put(tig.team.name, Pair.create(tig.withAttribs(tiga), oldEntry.second)); + } else { + Log.e("Netplay", "Hog count update for unknown team "+msg.obj); + } + break; + } default: { Log.e("FromNetHandler", "Unknown message type: "+msg.what); break; @@ -336,7 +405,7 @@ private static class ThreadedNetConnection { private static final long TICK_INTERVAL_FAST = 100; private static final long TICK_INTERVAL_SLOW = 5000; - private static final JnaFrontlib FLIB = Flib.INSTANCE; + private static final Frontlib FLIB = Flib.INSTANCE; public final ToNetHandler toNetHandler; @@ -399,6 +468,12 @@ FLIB.flib_netconn_onPasswordRequest(conn, passwordRequestCb, null); FLIB.flib_netconn_onEnterRoom(conn, enterRoomCb, null); FLIB.flib_netconn_onLeaveRoom(conn, leaveRoomCb, null); + FLIB.flib_netconn_onReadyState(conn, readyStateCb, null); + FLIB.flib_netconn_onTeamAdd(conn, teamAddedCb, null); + FLIB.flib_netconn_onTeamDelete(conn, teamDeletedCb, null); + FLIB.flib_netconn_onTeamAccepted(conn, teamAcceptedCb, null); + FLIB.flib_netconn_onTeamColorChanged(conn, teamColorChangedCb, null); + FLIB.flib_netconn_onHogCountChanged(conn, hogCountChangedCb, null); FLIB.flib_metascheme_release(meta); tickHandler.start(); @@ -496,7 +571,7 @@ private final BoolCallback enterRoomCb = new BoolCallback() { public void callback(Pointer context, boolean isChief) { - sendFromNet(FromNetHandler.MSG_ENTER_ROOM_FROM_LOBBY, Boolean.TRUE); + sendFromNet(FromNetHandler.MSG_ENTER_ROOM_FROM_LOBBY, isChief); } }; @@ -506,6 +581,42 @@ } }; + private final StrBoolCallback readyStateCb = new StrBoolCallback() { + public void callback(Pointer context, String player, boolean ready) { + sendFromNet(FromNetHandler.MSG_READYSTATE, Pair.create(player, ready)); + } + }; + + private final TeamCallback teamAddedCb = new TeamCallback() { + public void callback(Pointer context, TeamPtr team) { + sendFromNet(FromNetHandler.MSG_TEAM_ADDED, team.deref()); + } + }; + + private final StrCallback teamDeletedCb = new StrCallback() { + public void callback(Pointer context, String teamName) { + sendFromNet(FromNetHandler.MSG_TEAM_DELETED, teamName); + } + }; + + private final StrCallback teamAcceptedCb = new StrCallback() { + public void callback(Pointer context, String teamName) { + sendFromNet(FromNetHandler.MSG_TEAM_ACCEPTED, teamName); + } + }; + + private final StrIntCallback teamColorChangedCb = new StrIntCallback() { + public void callback(Pointer context, String teamName, int colorIndex) { + sendFromNet(FromNetHandler.MSG_TEAM_COLOR_CHANGED, colorIndex, teamName); + } + }; + + private final StrIntCallback hogCountChangedCb = new StrIntCallback() { + public void callback(Pointer context, String teamName, int hogCount) { + sendFromNet(FromNetHandler.MSG_HOG_COUNT_CHANGED, hogCount, teamName); + } + }; + private void shutdown(boolean error, String message) { if(conn != null) { FLIB.flib_netconn_destroy(conn); @@ -518,7 +629,7 @@ private final IntStrCallback disconnectCb = new IntStrCallback() { public void callback(Pointer context, int reason, String message) { - Boolean error = reason != JnaFrontlib.NETCONN_DISCONNECT_NORMAL; + Boolean error = reason != Frontlib.NETCONN_DISCONNECT_NORMAL; String messageForUser = createDisconnectUserMessage(appContext.getResources(), reason, message); shutdown(error, messageForUser); } @@ -526,13 +637,13 @@ private static String createDisconnectUserMessage(Resources res, int reason, String message) { switch(reason) { - case JnaFrontlib.NETCONN_DISCONNECT_AUTH_FAILED: + case Frontlib.NETCONN_DISCONNECT_AUTH_FAILED: return res.getString(R.string.error_auth_failed); - case JnaFrontlib.NETCONN_DISCONNECT_CONNLOST: + case Frontlib.NETCONN_DISCONNECT_CONNLOST: return res.getString(R.string.error_connection_lost); - case JnaFrontlib.NETCONN_DISCONNECT_INTERNAL_ERROR: + case Frontlib.NETCONN_DISCONNECT_INTERNAL_ERROR: return res.getString(R.string.error_unexpected, message); - case JnaFrontlib.NETCONN_DISCONNECT_SERVER_TOO_OLD: + case Frontlib.NETCONN_DISCONNECT_SERVER_TOO_OLD: return res.getString(R.string.error_server_too_old); default: return message; @@ -550,6 +661,7 @@ /** * Processes messages to the networking system. Runs on a non-main thread. */ + @SuppressLint("HandlerLeak") public final class ToNetHandler extends Handler { public static final int MSG_SEND_NICK = 0; public static final int MSG_SEND_PASSWORD = 1; @@ -561,8 +673,9 @@ public static final int MSG_SEND_JOIN_ROOM = 7; public static final int MSG_SEND_CREATE_ROOM = 8; public static final int MSG_SEND_LEAVE_ROOM = 9; + public static final int MSG_SEND_KICK = 10; - public static final int MSG_DISCONNECT = 10; + public static final int MSG_DISCONNECT = 11; public ToNetHandler(Looper looper) { super(looper); @@ -615,6 +728,10 @@ } break; } + case MSG_SEND_KICK: { + FLIB.flib_netconn_send_kick(conn, (String)msg.obj); + break; + } case MSG_DISCONNECT: { FLIB.flib_netconn_send_quit(conn, (String)msg.obj); shutdown(false, "User quit"); diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetplayStateFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetplayStateFragment.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetplayStateFragment.java Mon Aug 06 22:39:36 2012 +0200 @@ -1,6 +1,7 @@ package org.hedgewars.hedgeroid.netplay; import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.frontlib.Frontlib; import org.hedgewars.hedgeroid.netplay.Netplay.State; import android.app.Activity; @@ -101,9 +102,9 @@ @Override public void onReceive(Context context, Intent intent) { int reason = intent.getIntExtra(Netplay.EXTRA_REASON, -1); - if(reason == JnaFrontlib.NETCONN_ROOMLEAVE_ABANDONED) { + if(reason == Frontlib.NETCONN_ROOMLEAVE_ABANDONED) { Toast.makeText(appContext, R.string.toast_room_abandoned, Toast.LENGTH_LONG).show(); - } else if(reason == JnaFrontlib.NETCONN_ROOMLEAVE_KICKED) { + } else if(reason == Frontlib.NETCONN_ROOMLEAVE_KICKED) { Toast.makeText(appContext, R.string.toast_kicked, Toast.LENGTH_LONG).show(); } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ObservableTreeMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ObservableTreeMap.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,43 @@ +package org.hedgewars.hedgeroid.netplay; + +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; + +import android.database.DataSetObservable; + +public class ObservableTreeMap extends DataSetObservable { + private final Map map = new TreeMap(); + + public void replaceContent(Map newMap) { + map.clear(); + map.putAll(newMap); + notifyChanged(); + } + + public void put(K key, V value) { + map.put(key, value); + notifyChanged(); + } + + public V get(K key) { + return map.get(key); + } + + public void remove(K key) { + if(map.remove(key) != null) { + notifyChanged(); + } + } + + public void clear() { + if(!map.isEmpty()) { + map.clear(); + notifyChanged(); + } + } + + public Map getMap() { + return Collections.unmodifiableMap(map); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ObservableTreeMapAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ObservableTreeMapAdapter.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,62 @@ +package org.hedgewars.hedgeroid.netplay; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import android.database.DataSetObserver; +import android.widget.BaseAdapter; + +public abstract class ObservableTreeMapAdapter extends BaseAdapter { + private boolean sourceChanged = true; + private List entries = new ArrayList(); + private ObservableTreeMap source; + + private DataSetObserver observer = new DataSetObserver() { + @Override + public void onChanged() { + sourceChanged = true; + notifyDataSetChanged(); + } + + @Override + public void onInvalidated() { + invalidate(); + } + }; + + abstract protected Comparator getEntryOrder(); + + protected List getEntries() { + if(sourceChanged) { + entries.clear(); + entries.addAll(source.getMap().values()); + Collections.sort(entries, getEntryOrder()); + sourceChanged = false; + } + return entries; + } + + public int getCount() { + return getEntries().size(); + } + + public void setSource(ObservableTreeMap source) { + if(this.source != null) { + this.source.unregisterObserver(observer); + } + this.source = source; + this.source.registerObserver(observer); + sourceChanged = true; + notifyDataSetChanged(); + } + + public void invalidate() { + if(source != null) { + source.unregisterObserver(observer); + } + source = null; + notifyDataSetInvalidated(); + } +} \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Player.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Player.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; - -public class Player { - public final String name; - - public Player(String name) { - this.name = name; - } -} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/PlayerList.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/PlayerList.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; - -import java.util.Collections; -import java.util.Map; -import java.util.TreeMap; - -import android.database.DataSetObservable; -import android.util.Pair; - -public class Playerlist extends DataSetObservable { - private long nextId = 1; - private Map> players = new TreeMap>(); - - public void addPlayerWithNewId(String name) { - players.put(name, Pair.create(new Player(name), nextId++)); - notifyChanged(); - } - - public void removePlayer(String name) { - if(players.remove(name) != null) { - notifyChanged(); - } - } - - public void clear() { - if(!players.isEmpty()) { - players.clear(); - notifyChanged(); - } - } - - public Map> getMap() { - return Collections.unmodifiableMap(players); - } -} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/PlayerListAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/PlayerListAdapter.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.hedgewars.hedgeroid.R; - -import android.content.Context; -import android.database.DataSetObserver; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.TextView; - -public class PlayerlistAdapter extends BaseAdapter { - private List> players = new ArrayList>(); - private Context context; - private Playerlist playerlist; - - private DataSetObserver observer = new DataSetObserver() { - @Override - public void onChanged() { - reloadFromList(playerlist); - } - - @Override - public void onInvalidated() { - invalidate(); - } - }; - - public PlayerlistAdapter(Context context) { - this.context = context; - } - - public int getCount() { - return players.size(); - } - - public Player getItem(int position) { - return players.get(position).first; - } - - public long getItemId(int position) { - return players.get(position).second; - } - - public boolean hasStableIds() { - return true; - } - - public void setList(Playerlist playerlist) { - if(this.playerlist != null) { - this.playerlist.unregisterObserver(observer); - } - this.playerlist = playerlist; - this.playerlist.registerObserver(observer); - reloadFromList(playerlist); - } - - public void invalidate() { - if(playerlist != null) { - playerlist.unregisterObserver(observer); - } - playerlist = null; - notifyDataSetInvalidated(); - } - - private void reloadFromList(Playerlist list) { - players = new ArrayList>(list.getMap().values()); - Collections.sort(players, AlphabeticalOrderComparator.INSTANCE); - notifyDataSetChanged(); - } - - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = LayoutInflater.from(context); - v = vi.inflate(R.layout.listview_player, null); - } - - String player = players.get(position).first.name; - TextView username = (TextView) v.findViewById(android.R.id.text1); - username.setText(player); - return v; - } - - private static final class AlphabeticalOrderComparator implements Comparator> { - public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator(); - public int compare(Pair lhs, Pair rhs) { - return lhs.first.name.compareToIgnoreCase(rhs.first.name); - }; - } -} \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/PlayerlistFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/PlayerlistFragment.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; - -import org.hedgewars.hedgeroid.R; - -import android.os.Bundle; -import android.support.v4.app.ListFragment; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView.AdapterContextMenuInfo; - -public class PlayerlistFragment extends ListFragment { - private Netplay netconn; - private PlayerlistAdapter playerListAdapter; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - netconn = Netplay.getAppInstance(getActivity().getApplicationContext()); - playerListAdapter = new PlayerlistAdapter(getActivity()); - playerListAdapter.setList(Netplay.getAppInstance(getActivity().getApplicationContext()).playerList); - setListAdapter(playerListAdapter); - } - - @Override - public void onDestroy() { - super.onDestroy(); - playerListAdapter.invalidate(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - registerForContextMenu(getListView()); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - MenuInflater inflater = getActivity().getMenuInflater(); - inflater.inflate(R.menu.lobby_playerlist_context, menu); - menu.setHeaderIcon(R.drawable.human); - menu.setHeaderTitle(playerListAdapter.getItem(info.position).name); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); - Player player = playerListAdapter.getItem(info.position); - switch(item.getItemId()) { - case R.id.player_info: - netconn.sendPlayerInfoQuery(player.name); - return true; - case R.id.player_follow: - netconn.sendFollowPlayer(player.name); - return true; - default: - return super.onContextItemSelected(item); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.lobby_players_fragment, container, false); - } -} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Room.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Room.java Mon Aug 06 22:33:07 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -package org.hedgewars.hedgeroid.netplay; - -import org.hedgewars.hedgeroid.R; - -import android.content.res.Resources; - -public class Room { - public static final String MAP_REGULAR = "+rnd+"; - public static final String MAP_MAZE = "+maze+"; - public static final String MAP_DRAWN = "+drawn+"; - - public final String name, map, scheme, weapons, owner; - public final int playerCount, teamCount; - public final boolean inProgress; - - public Room(String name, String map, String scheme, String weapons, - String owner, int playerCount, int teamCount, boolean inProgress) { - this.name = name; - this.map = map; - this.scheme = scheme; - this.weapons = weapons; - this.owner = owner; - this.playerCount = playerCount; - this.teamCount = teamCount; - this.inProgress = inProgress; - } - - public static String formatMapName(Resources res, String map) { - if(map.charAt(0)=='+') { - if(map.equals(MAP_REGULAR)) { - return res.getString(R.string.map_regular); - } else if(map.equals(MAP_MAZE)) { - return res.getString(R.string.map_maze); - } else if(map.equals(MAP_DRAWN)) { - return res.getString(R.string.map_drawn); - } - } - return map; - } -} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomActivity.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomActivity.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomActivity.java Mon Aug 06 22:39:36 2012 +0200 @@ -1,18 +1,12 @@ package org.hedgewars.hedgeroid.netplay; import org.hedgewars.hedgeroid.R; -import org.hedgewars.hedgeroid.netplay.JnaFrontlib.NetconnPtr; import org.hedgewars.hedgeroid.netplay.Netplay.State; import org.hedgewars.hedgeroid.netplay.NetplayStateFragment.NetplayStateListener; -import android.content.Intent; -import android.content.IntentFilter; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; -import android.support.v4.content.LocalBroadcastManager; -import android.widget.LinearLayout; import android.widget.TabHost; import android.widget.Toast; diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomList.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomList.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomList.java Mon Aug 06 22:39:36 2012 +0200 @@ -1,64 +1,39 @@ package org.hedgewars.hedgeroid.netplay; -import java.util.Collections; import java.util.Map; import java.util.TreeMap; -import android.database.DataSetObservable; -import android.util.Log; +import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom; + import android.util.Pair; -public class Roomlist extends DataSetObservable { +public class Roomlist extends ObservableTreeMap> { private long nextId = 1; - private Map> rooms = new TreeMap>(); - public void updateList(Room[] newRooms) { - Map> newMap = new TreeMap>(); - for(Room room : newRooms) { - Pair oldEntry = rooms.get(room.name); + public void updateList(RoomlistRoom[] newRooms) { + Map> newMap = new TreeMap>(); + for(RoomlistRoom room : newRooms) { + Pair oldEntry = get(room.name); if(oldEntry == null) { newMap.put(room.name, Pair.create(room, nextId++)); } else { newMap.put(room.name, Pair.create(room, oldEntry.second)); } } - rooms = newMap; - notifyChanged(); + replaceContent(newMap); } - public void addRoomWithNewId(Room room) { - rooms.put(room.name, Pair.create(room, nextId++)); - notifyChanged(); + public void addRoomWithNewId(RoomlistRoom room) { + put(room.name, Pair.create(room, nextId++)); } - public void updateRoom(String name, Room room) { - Pair oldEntry = rooms.get(name); + public void updateRoom(String name, RoomlistRoom room) { + Pair oldEntry = get(name); if(oldEntry == null) { - Log.e("RoomList", "Received update for unknown room: "+name); - rooms.put(room.name, Pair.create(room, nextId++)); + addRoomWithNewId(room); } else { - if(!name.equals(room.name)) { - rooms.remove(name); - } - rooms.put(room.name, Pair.create(room, oldEntry.second)); - } - notifyChanged(); - } - - public void removeRoom(String name) { - if(rooms.remove(name) != null) { - notifyChanged(); + remove(name); + put(room.name, Pair.create(room, oldEntry.second)); } } - - public void clear() { - if(!rooms.isEmpty()) { - rooms.clear(); - notifyChanged(); - } - } - - public Map> getMap() { - return Collections.unmodifiableMap(rooms); - } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomListAdapter.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomListAdapter.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomListAdapter.java Mon Aug 06 22:39:36 2012 +0200 @@ -1,85 +1,45 @@ package org.hedgewars.hedgeroid.netplay; -import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; -import java.util.List; import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom; import android.content.Context; import android.content.res.Resources; -import android.database.DataSetObserver; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseAdapter; import android.widget.TextView; -public class RoomlistAdapter extends BaseAdapter { - private List> rooms = new ArrayList>(); +public class RoomlistAdapter extends ObservableTreeMapAdapter> { private Context context; - private Roomlist roomlist; - - private DataSetObserver observer = new DataSetObserver() { - @Override - public void onChanged() { - reloadFromList(roomlist); - } - - @Override - public void onInvalidated() { - invalidate(); - } - }; public RoomlistAdapter(Context context) { this.context = context; } - public int getCount() { - return rooms.size(); + @Override + protected Comparator> getEntryOrder() { + return RoomAgeComparator.INSTANCE; } - - public Room getItem(int position) { - return rooms.get(position).first; + + public RoomlistRoom getItem(int position) { + return getEntries().get(position).first; } public long getItemId(int position) { - return rooms.get(position).second; + return getEntries().get(position).second; } public boolean hasStableIds() { return true; } - - public void setList(Roomlist roomlist) { - if(this.roomlist != null) { - this.roomlist.unregisterObserver(observer); - } - this.roomlist = roomlist; - this.roomlist.registerObserver(observer); - reloadFromList(roomlist); - } - public void invalidate() { - if(roomlist != null) { - roomlist.unregisterObserver(observer); - } - roomlist = null; - notifyDataSetInvalidated(); - } - - private void reloadFromList(Roomlist list) { - rooms = new ArrayList>(roomlist.getMap().values()); - Collections.sort(rooms, RoomAgeComparator.INSTANCE); - notifyDataSetChanged(); - } - - private static CharSequence formatExtra(Resources res, Room room) { + private static CharSequence formatExtra(Resources res, RoomlistRoom room) { String ownermsg = res.getString(R.string.roomlist_owner, room.owner); - String mapmsg = res.getString(R.string.roomlist_map, Room.formatMapName(res, room.map)); + String mapmsg = res.getString(R.string.roomlist_map, RoomlistRoom.formatMapName(res, room.map)); String scheme = room.scheme.equals(room.weapons) ? room.scheme : room.scheme + " / " + room.weapons; String schememsg = res.getString(R.string.roomlist_scheme, scheme); return ownermsg + ". " + mapmsg + ", " + schememsg; @@ -92,7 +52,7 @@ v = vi.inflate(R.layout.listview_room, null); } - Room room = rooms.get(position).first; + RoomlistRoom room = getItem(position); int iconRes = room.inProgress ? R.drawable.roomlist_ingame : R.drawable.roomlist_preparing; if(v.findViewById(android.R.id.text1) == null) { @@ -114,7 +74,7 @@ teamCountView.setText(String.valueOf(room.teamCount)); } ownerView.setText(room.owner); - mapView.setText(Room.formatMapName(context.getResources(), room.map)); + mapView.setText(RoomlistRoom.formatMapName(context.getResources(), room.map)); schemeView.setText(room.scheme); weaponView.setText(room.weapons); } else { @@ -130,9 +90,9 @@ return v; } - private static final class RoomAgeComparator implements Comparator> { + private static final class RoomAgeComparator implements Comparator> { public static final RoomAgeComparator INSTANCE = new RoomAgeComparator(); - public int compare(Pair lhs, Pair rhs) { + public int compare(Pair lhs, Pair rhs) { return rhs.second.compareTo(lhs.second); } } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomPlayerlist.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomPlayerlist.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,36 @@ +package org.hedgewars.hedgeroid.netplay; + +import org.hedgewars.hedgeroid.Datastructures.Player; +import org.hedgewars.hedgeroid.netplay.RoomPlayerlist.PlayerInRoom; + +import android.util.Log; + +public class RoomPlayerlist extends ObservableTreeMap { + private long nextId = 1; + + public void addPlayerWithNewId(String name) { + put(name, new PlayerInRoom(new Player(name), nextId++, false)); + } + + public void setReady(String name, boolean ready) { + PlayerInRoom oldEntry = get(name); + if(oldEntry==null) { + Log.e("RoomPlayerlist", "Setting readystate for unknown player "+name); + } else { + put(name, new PlayerInRoom(oldEntry.player, oldEntry.id, ready)); + } + } + + // Immutable + public static class PlayerInRoom { + public final Player player; + public final long id; + public final boolean ready; + + public PlayerInRoom(Player player, long id, boolean ready) { + this.player = player; + this.id = id; + this.ready = ready; + } + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomPlayerlistAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomPlayerlistAdapter.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,59 @@ +package org.hedgewars.hedgeroid.netplay; + +import java.util.Comparator; + +import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.netplay.RoomPlayerlist.PlayerInRoom; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +public class RoomPlayerlistAdapter extends ObservableTreeMapAdapter { + private Context context; + + public RoomPlayerlistAdapter(Context context) { + this.context = context; + } + + @Override + protected Comparator getEntryOrder() { + return AlphabeticalOrderComparator.INSTANCE; + } + + public PlayerInRoom getItem(int position) { + return getEntries().get(position); + } + + public long getItemId(int position) { + return getEntries().get(position).id; + } + + public boolean hasStableIds() { + return true; + } + + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(context); + v = vi.inflate(R.layout.listview_player, null); + } + + PlayerInRoom player = getItem(position); + TextView username = (TextView) v.findViewById(android.R.id.text1); + username.setText(player.player.name); + int readyDrawable = player.ready ? R.drawable.lightbulb_on : R.drawable.lightbulb_off; + username.setCompoundDrawablesWithIntrinsicBounds(readyDrawable, 0, 0, 0); + return v; + } + + private static final class AlphabeticalOrderComparator implements Comparator { + public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator(); + public int compare(PlayerInRoom lhs, PlayerInRoom rhs) { + return lhs.player.name.compareToIgnoreCase(rhs.player.name); + }; + } +} \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomPlayerlistFragment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomPlayerlistFragment.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,79 @@ +package org.hedgewars.hedgeroid.netplay; + +import org.hedgewars.hedgeroid.R; +import org.hedgewars.hedgeroid.netplay.RoomPlayerlist.PlayerInRoom; + +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView.AdapterContextMenuInfo; + +public class RoomPlayerlistFragment extends ListFragment { + private Netplay netplay; + private RoomPlayerlistAdapter adapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new RoomPlayerlistAdapter(getActivity()); + adapter.setSource(netplay.roomPlayerlist); + setListAdapter(adapter); + } + + @Override + public void onDestroy() { + super.onDestroy(); + adapter.invalidate(); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + registerForContextMenu(getListView()); + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; + String playerName = adapter.getItem(info.position).player.name; + + MenuInflater inflater = getActivity().getMenuInflater(); + inflater.inflate(R.menu.room_playerlist_context, menu); + if(netplay.isChief() && !playerName.equals(netplay.getPlayerName())) { + inflater.inflate(R.menu.room_playerlist_chief_context, menu); + } + menu.setHeaderIcon(R.drawable.human); + menu.setHeaderTitle(playerName); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo(); + PlayerInRoom player = adapter.getItem(info.position); + switch(item.getItemId()) { + case R.id.player_info: + netplay.sendPlayerInfoQuery(player.player.name); + return true; + case R.id.player_kick: + netplay.sendKick(player.player.name); + return true; + default: + return super.onContextItemSelected(item); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_playerlist, container, false); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomlistFragment.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomlistFragment.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RoomlistFragment.java Mon Aug 06 22:39:36 2012 +0200 @@ -31,7 +31,7 @@ super.onCreate(savedInstanceState); netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); adapter = new RoomlistAdapter(getActivity()); - adapter.setList(netplay.roomList); + adapter.setSource(netplay.roomList); setListAdapter(adapter); } diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Teamlist.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Teamlist.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,13 @@ +package org.hedgewars.hedgeroid.netplay; + +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; + +import android.util.Pair; + +public class Teamlist extends ObservableTreeMap> { + private long nextId = 1; + + public void addTeamWithNewId(TeamInGame team) { + put(team.team.name, Pair.create(team, nextId++)); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TeamlistAdapter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TeamlistAdapter.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,60 @@ +package org.hedgewars.hedgeroid.netplay; + +import java.util.Comparator; + +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; + +import android.content.Context; +import android.util.Pair; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +public class TeamlistAdapter extends ObservableTreeMapAdapter> { + private Context context; + + public TeamlistAdapter(Context context) { + this.context = context; + } + + @Override + protected Comparator> getEntryOrder() { + return AlphabeticalOrderComparator.INSTANCE; + } + + public TeamInGame getItem(int position) { + return getEntries().get(position).first; + } + + public long getItemId(int position) { + return getEntries().get(position).second; + } + + public boolean hasStableIds() { + return true; + } + + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = LayoutInflater.from(context); + v = vi.inflate(android.R.layout.simple_list_item_2, null); + } + + TeamInGame team = getItem(position); + TextView tv1 = (TextView) v.findViewById(android.R.id.text1); + TextView tv2 = (TextView) v.findViewById(android.R.id.text2); + + tv1.setText(team.team.name); + tv2.setText("Hogs: "+team.ingameAttribs.hogCount); + return v; + } + + private static final class AlphabeticalOrderComparator implements Comparator> { + public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator(); + public int compare(Pair lhs, Pair rhs) { + return lhs.first.team.name.compareToIgnoreCase(rhs.first.team.name); + }; + } +} \ No newline at end of file diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TeamlistFragment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TeamlistFragment.java Mon Aug 06 22:39:36 2012 +0200 @@ -0,0 +1,35 @@ +package org.hedgewars.hedgeroid.netplay; + +import org.hedgewars.hedgeroid.R; + +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class TeamlistFragment extends ListFragment { + private Netplay netplay; + private TeamlistAdapter adapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + netplay = Netplay.getAppInstance(getActivity().getApplicationContext()); + adapter = new TeamlistAdapter(getActivity()); + adapter.setSource(netplay.roomTeamlist); + setListAdapter(adapter); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_teamlist, container, false); + } + + @Override + public void onDestroy() { + super.onDestroy(); + adapter.invalidate(); + } +} diff -r 45b9f25ff611 -r 2fb781bbdd51 project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TickHandler.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TickHandler.java Mon Aug 06 22:33:07 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/TickHandler.java Mon Aug 06 22:39:36 2012 +0200 @@ -12,7 +12,7 @@ * The interval can be changed at any time, which will cause * an immediate execution of the runnable again. */ -class TickHandler extends Handler { +public class TickHandler extends Handler { private final Runnable callback; private int messageId; private long interval;