diff --git a/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/MiningSettingsDAOBean.java b/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/MiningSettingsDAOBean.java
index 57047b9..e2585f3 100644
--- a/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/MiningSettingsDAOBean.java
+++ b/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/MiningSettingsDAOBean.java
@@ -27,12 +27,18 @@ class MiningSettingsDAOBean
 	/** <code>emp.mset_update_start(INT)</code> stored procedure */
 	private StoredProc pStartEmpireUpdate;
 
+	/** <code>emp.mset_update_start(INT,INT)</code> stored procedure */
+	private StoredProc pStartPlanetUpdate;
+
 	/** <code>emp.mset_update_set(TEXT,INT)</code> stored procedure */
 	private StoredProc pSetMiningPriority;
 
 	/** <code>emp.mset_update_apply()</code> stored procedure */
 	private StoredProc pApplyUpdate;
 
+	/** <code>emp.mset_toggle_source(INT,INT)</code> stored procedure */
+	private StoredProc pToggleSource;
+
 
 	/**
 	 * Dependency injector that sets the data source
@@ -47,6 +53,11 @@ class MiningSettingsDAOBean
 		this.pStartEmpireUpdate.addParameter( "_empire" , Types.INTEGER );
 		this.pStartEmpireUpdate.addOutput( "_success" , Types.BOOLEAN );
 
+		this.pStartPlanetUpdate = new StoredProc( dataSource , "emp" , "mset_update_start" );
+		this.pStartPlanetUpdate.addParameter( "_empire" , Types.INTEGER );
+		this.pStartPlanetUpdate.addParameter( "_planet" , Types.INTEGER );
+		this.pStartPlanetUpdate.addOutput( "_success" , Types.BOOLEAN );
+
 		this.pSetMiningPriority = new StoredProc( dataSource , "emp" , "mset_update_set" );
 		this.pSetMiningPriority.addParameter( "_resource" , Types.VARCHAR );
 		this.pSetMiningPriority.addParameter( "_priority" , Types.INTEGER );
@@ -54,6 +65,10 @@ class MiningSettingsDAOBean
 
 		this.pApplyUpdate = new StoredProc( dataSource , "emp" , "mset_update_apply" );
 		this.pApplyUpdate.addOutput( "_success" , Types.BOOLEAN );
+
+		this.pToggleSource = new StoredProc( dataSource , "emp" , "mset_toggle_source" );
+		this.pToggleSource.addParameter( "_empire" , Types.INTEGER );
+		this.pToggleSource.addParameter( "_planet" , Types.INTEGER );
 	}
 
 
@@ -65,6 +80,14 @@ class MiningSettingsDAOBean
 	}
 
 
+	/* Documented in interface */
+	@Override
+	public boolean startUpdate( int empire , int planet )
+	{
+		return (Boolean) this.pStartPlanetUpdate.execute( empire , planet ).get( "_success" );
+	}
+
+
 	/* Documented in interface */
 	@Override
 	public boolean setNewPriority( String resource , int priority )
@@ -80,4 +103,12 @@ class MiningSettingsDAOBean
 		return (Boolean) this.pApplyUpdate.execute( ).get( "_success" );
 	}
 
+
+	/* Documented in interface */
+	@Override
+	public void togglePlanet( int empire , int planet )
+	{
+		this.pToggleSource.execute( empire , planet );
+	}
+
 }
diff --git a/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/ResourcesControllerBean.java b/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/ResourcesControllerBean.java
index a2b8040..1829713 100644
--- a/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/ResourcesControllerBean.java
+++ b/legacyworlds-server-beans-resources/src/main/java/com/deepclone/lw/beans/game/resources/ResourcesControllerBean.java
@@ -52,12 +52,51 @@ class ResourcesControllerBean
 	@Override
 	public void updateEmpireSettings( int empireId , Map< String , Integer > settings )
 	{
-		if ( !this.settings.startUpdate( empireId ) ) {
-			return;
+		if ( this.settings.startUpdate( empireId ) ) {
+			this.sendMiningSettings( settings );
 		}
+	}
 
+
+	/* Documented in interface */
+	@Override
+	public void togglePlanet( int empire , int planet )
+	{
+		this.settings.togglePlanet( empire , planet );
+	}
+
+
+	/**
+	 * Update a planet's mining settings
+	 * 
+	 * <p>
+	 * Start a mining settings update for the specified planet / empire combination, then set each
+	 * resource-specific priority, then apply the update. Exit whenever something goes wrong.
+	 */
+	@Override
+	public void updatePlanetSettings( int empire , int planet , Map< String , Integer > settings )
+	{
+		if ( this.settings.startUpdate( empire , planet ) ) {
+			this.sendMiningSettings( settings );
+		}
+	}
+
+
+	/**
+	 * Send mining settings to the database
+	 * 
+	 * <p>
+	 * This method is called once a mining settings update has been started (whether it's a
+	 * planet-specific or empire-wide update). It sends all settings to the database server, and
+	 * aborts if anything goes wrong.
+	 * 
+	 * @param settings
+	 *            the settings to upload
+	 */
+	private void sendMiningSettings( Map< String , Integer > settings )
+	{
 		for ( Map.Entry< String , Integer > entry : settings.entrySet( ) ) {
-			if ( ! this.settings.setNewPriority( entry.getKey( ) , entry.getValue( ) ) ) {
+			if ( !this.settings.setNewPriority( entry.getKey( ) , entry.getValue( ) ) ) {
 				return;
 			}
 		}
diff --git a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetDAOBean.java b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetDAOBean.java
index 8deb049..e9a1cf9 100644
--- a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetDAOBean.java
+++ b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetDAOBean.java
@@ -101,6 +101,7 @@ public class PlanetDAOBean
 				info.setRenamePossible( rs.getBoolean( "can_rename" ) );
 				info.setAbandonPossible( rs.getBoolean( "can_abandon" ) );
 				info.setAbandonTime( rs.getInt( "abandon_time" ) );
+				info.setOwnSettings( rs.getBoolean( "specific_mining_settings" ) );
 				return info;
 			}
 		};
diff --git a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetsManagementBean.java b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetsManagementBean.java
index 0e364ca..8d5bf13 100644
--- a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetsManagementBean.java
+++ b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/map/PlanetsManagementBean.java
@@ -109,6 +109,7 @@ public class PlanetsManagementBean
 		view.sethChange( data.gethChange( ) );
 		view.setIncome( data.getIncome( ) );
 		view.setUpkeep( data.getUpkeep( ) );
+		view.setOwnMiningSettings( data.isOwnSettings( ) );
 
 		view.setCivQueue( this.planetDao.getConstructionQueue( planetId ) );
 		view.setMilQueue( this.planetDao.getMilitaryQueue( planetId ) );
diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/ToggleMiningSettingsCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/ToggleMiningSettingsCommandDelegateBean.java
new file mode 100644
index 0000000..f4a951a
--- /dev/null
+++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/ToggleMiningSettingsCommandDelegateBean.java
@@ -0,0 +1,73 @@
+package com.deepclone.lw.beans.user.player.game.planets;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate;
+import com.deepclone.lw.beans.user.abst.SessionCommandHandler;
+import com.deepclone.lw.beans.user.player.GameSubTypeBean;
+import com.deepclone.lw.cmd.player.planets.ToggleMiningSettingsCommand;
+import com.deepclone.lw.cmd.player.planets.ViewPlanetCommand;
+import com.deepclone.lw.interfaces.game.resources.ResourcesController;
+import com.deepclone.lw.interfaces.session.ServerSession;
+import com.deepclone.lw.session.Command;
+import com.deepclone.lw.session.CommandResponse;
+import com.deepclone.lw.session.NullResponse;
+
+
+
+/**
+ * Command handler for {@link ToggleMiningSettingsCommand}
+ * 
+ * @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
+ */
+class ToggleMiningSettingsCommandDelegateBean
+		implements AutowiredCommandDelegate
+{
+
+	/** The resources controller */
+	private ResourcesController resourcesController;
+
+
+	/**
+	 * Dependency injector that sets the resources controller
+	 * 
+	 * @param resourcesController
+	 *            the resources controller
+	 */
+	@Autowired( required = true )
+	public void setResourcesController( ResourcesController resourcesController )
+	{
+		this.resourcesController = resourcesController;
+	}
+
+
+	/** This class handles {@link ToggleMiningSettingsCommand} instances */
+	@Override
+	public Class< ? extends Command > getType( )
+	{
+		return ToggleMiningSettingsCommand.class;
+	}
+
+
+	/** This class is enabled for the {@link GameSubTypeBean} session type */
+	@Override
+	public Class< ? extends SessionCommandHandler > getCommandHandler( )
+	{
+		return GameSubTypeBean.class;
+	}
+
+
+	/** If the account is not in vacation mode, try to toggle the planet's settings */
+	@Override
+	public CommandResponse execute( ServerSession session , Command command )
+	{
+		if ( !session.get( "vacation" , Boolean.class ) ) {
+			int empireId = session.get( "empireId" , Integer.class );
+			ViewPlanetCommand planet = (ViewPlanetCommand) command;
+			this.resourcesController.togglePlanet( empireId , planet.getId( ) );
+		}
+		return new NullResponse( );
+	}
+
+}
diff --git a/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/UpdatePlanetMiningSettingsCommandDelegateBean.java b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/UpdatePlanetMiningSettingsCommandDelegateBean.java
new file mode 100644
index 0000000..1a7d954
--- /dev/null
+++ b/legacyworlds-server-beans-user/src/main/java/com/deepclone/lw/beans/user/player/game/planets/UpdatePlanetMiningSettingsCommandDelegateBean.java
@@ -0,0 +1,72 @@
+package com.deepclone.lw.beans.user.player.game.planets;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate;
+import com.deepclone.lw.beans.user.abst.SessionCommandHandler;
+import com.deepclone.lw.beans.user.player.GameSubTypeBean;
+import com.deepclone.lw.cmd.player.planets.UpdatePlanetMiningSettingsCommand;
+import com.deepclone.lw.interfaces.game.resources.ResourcesController;
+import com.deepclone.lw.interfaces.session.ServerSession;
+import com.deepclone.lw.session.Command;
+import com.deepclone.lw.session.CommandResponse;
+import com.deepclone.lw.session.NullResponse;
+
+
+
+/**
+ * Command handler for {@link UpdatePlanetMiningSettingsCommand}
+ * 
+ * @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
+ */
+class UpdatePlanetMiningSettingsCommandDelegateBean
+		implements AutowiredCommandDelegate
+{
+
+	/** The resources controller */
+	private ResourcesController resourcesController;
+
+
+	/**
+	 * Dependency injector that sets the resources controller
+	 * 
+	 * @param resourcesController
+	 *            the resources controller
+	 */
+	@Autowired( required = true )
+	public void setResourcesController( ResourcesController resourcesController )
+	{
+		this.resourcesController = resourcesController;
+	}
+
+
+	/** This class handles {@link UpdatePlanetMiningSettingsCommand} instances */
+	@Override
+	public Class< ? extends Command > getType( )
+	{
+		return UpdatePlanetMiningSettingsCommand.class;
+	}
+
+
+	/** This class is enabled for the {@link GameSubTypeBean} session type */
+	@Override
+	public Class< ? extends SessionCommandHandler > getCommandHandler( )
+	{
+		return GameSubTypeBean.class;
+	}
+
+
+	/** If the empire is not in vacation mode, try updating the planet's mining priorities */
+	@Override
+	public CommandResponse execute( ServerSession session , Command command )
+	{
+		if ( !session.get( "vacation" , Boolean.class ) ) {
+			UpdatePlanetMiningSettingsCommand settings = (UpdatePlanetMiningSettingsCommand) command;
+			int empireId = session.get( "empireId" , Integer.class );
+			this.resourcesController.updatePlanetSettings( empireId , settings.getId( ) , settings.getSettings( ) );
+		}
+		return new NullResponse( );
+	}
+
+}
diff --git a/legacyworlds-server-beans-user/src/main/resources/configuration/session-types/player.xml b/legacyworlds-server-beans-user/src/main/resources/configuration/session-types/player.xml
index 203a345..ff9a382 100644
--- a/legacyworlds-server-beans-user/src/main/resources/configuration/session-types/player.xml
+++ b/legacyworlds-server-beans-user/src/main/resources/configuration/session-types/player.xml
@@ -61,6 +61,8 @@
 	<bean class="com.deepclone.lw.beans.user.player.game.planets.FlushQueueCommandDelegateBean" />
 	<bean class="com.deepclone.lw.beans.user.player.game.planets.RenamePlanetCommandDelegateBean" />
 	<bean class="com.deepclone.lw.beans.user.player.game.planets.AbandonPlanetCommandDelegateBean" />
+	<bean class="com.deepclone.lw.beans.user.player.game.planets.ToggleMiningSettingsCommandDelegateBean" />
+	<bean class="com.deepclone.lw.beans.user.player.game.planets.UpdatePlanetMiningSettingsCommandDelegateBean" />
 
 	<!-- Game: enemy list -->
 	<bean class="com.deepclone.lw.beans.user.player.game.elist.EnemyListCommandDelegateBean" />
diff --git a/legacyworlds-server-data/db-structure/parts/040-functions/045-empire-mining.sql b/legacyworlds-server-data/db-structure/parts/040-functions/045-empire-mining.sql
index d8b4f04..8704d68 100644
--- a/legacyworlds-server-data/db-structure/parts/040-functions/045-empire-mining.sql
+++ b/legacyworlds-server-data/db-structure/parts/040-functions/045-empire-mining.sql
@@ -69,8 +69,9 @@ GRANT EXECUTE
  *		_planet_id		The planet's identifier
  *
  * Returns:
- *		?				True if the empire exists and owns the planet, false
- *							otherwise
+ *		?				True if the empire exists and owns the planet and if
+ *							the planet is using planet-specific settings,
+ *							false otherwise
  */
 DROP FUNCTION IF EXISTS emp.mset_update_start( INT , INT );
 CREATE FUNCTION emp.mset_update_start( _empire_id INT , _planet_id INT )
@@ -95,9 +96,14 @@ BEGIN
 				ON _planet.name_id = _emp_planet.planet_id
 			INNER JOIN verse.resource_providers _resprov
 				ON _resprov.planet_id = _planet.name_id
+			INNER JOIN emp.planet_mining_settings _mset
+				ON _mset.planet_id = _planet.name_id
+					AND _mset.empire_id = _empire.name_id
+					AND _mset.resource_name_id = _resprov.resource_name_id
 		WHERE _empire.name_id = _empire_id
 				AND _planet.name_id = _planet_id
-		FOR SHARE OF _empire, _emp_planet , _planet , _resprov;
+		FOR SHARE OF _empire, _emp_planet , _planet , _resprov
+		FOR UPDATE OF _mset;
 	IF NOT FOUND THEN
 		RETURN FALSE;
 	END IF;
@@ -239,4 +245,71 @@ REVOKE EXECUTE
 	FROM PUBLIC;
 GRANT EXECUTE
 	ON FUNCTION emp.mset_update_apply( )
+	TO :dbuser;
+
+
+/*
+ * Toggle the source of a planet's mining settings
+ * ------------------------------------------------
+ * 
+ * This function causes a planet to be switched between empire-wide and
+ * planet-specific mining settings.
+ * 
+ * Parameters:
+ *		_empire		The empire's identifier
+ *		_planet		The planet's identifier
+ *
+ * Returns:
+ *		?			TRUE if the operation succeeded, FALSE if the planet
+ *						didn't exist or wasn't owned by the specified empire.
+ */
+DROP FUNCTION IF EXISTS emp.mset_toggle_source( INT , INT );
+CREATE FUNCTION emp.mset_toggle_source( _empire INT , _planet INT )
+		RETURNS BOOLEAN
+		LANGUAGE PLPGSQL
+		STRICT VOLATILE
+		SECURITY DEFINER
+	AS $mset_toggle_source$
+BEGIN
+	PERFORM 1
+		FROM emp.planets _ep
+			INNER JOIN verse.resource_providers _rp
+				USING ( planet_id )
+			LEFT OUTER JOIN (
+				SELECT * FROM emp.planet_mining_settings _pms
+					WHERE planet_id = _planet
+						AND empire_id = _empire
+					FOR UPDATE
+				) _pms USING ( planet_id , empire_id , resource_name_id )
+		WHERE _ep.empire_id = _empire
+			AND _ep.planet_id = _planet
+		FOR UPDATE OF _ep;
+	IF NOT FOUND THEN
+		RETURN FALSE;
+	END IF;
+
+	PERFORM 1 FROM emp.planet_mining_settings _pms
+		WHERE planet_id = _planet AND empire_id = _empire;
+	IF FOUND THEN
+		DELETE FROM emp.planet_mining_settings
+			WHERE planet_id = _planet AND empire_id = _empire;
+	ELSE
+		INSERT INTO emp.planet_mining_settings(
+				empire_id , planet_id , resource_name_id , emppmset_weight
+			) SELECT empire_id  , planet_id , resource_name_id , empmset_weight
+				FROM verse.resource_providers _rp
+					INNER JOIN emp.mining_settings
+						USING ( resource_name_id )
+				WHERE planet_id = _planet AND empire_id = _empire;
+	END IF;
+	
+	RETURN TRUE;
+END;
+$mset_toggle_source$;
+
+REVOKE EXECUTE
+	ON FUNCTION emp.mset_toggle_source( INT , INT )
+	FROM PUBLIC;
+GRANT EXECUTE
+	ON FUNCTION emp.mset_toggle_source( INT , INT )
 	TO :dbuser;
\ No newline at end of file
diff --git a/legacyworlds-server-data/db-structure/parts/040-functions/140-planets.sql b/legacyworlds-server-data/db-structure/parts/040-functions/140-planets.sql
index 53bca46..778b57d 100644
--- a/legacyworlds-server-data/db-structure/parts/040-functions/140-planets.sql
+++ b/legacyworlds-server-data/db-structure/parts/040-functions/140-planets.sql
@@ -36,14 +36,16 @@ CREATE TYPE planet_orbital_data AS (
 
 
 -- Planet owner view
-CREATE TYPE planet_owner_data AS (
-	happiness		INT ,
-	h_change		INT ,
-	income			BIGINT ,
-	upkeep			BIGINT ,
-	can_rename		BOOLEAN ,
-	can_abandon		BOOLEAN ,
-	abandon_time	INT
+DROP TYPE IF EXISTS emp.planet_owner_data;
+CREATE TYPE emp.planet_owner_data AS (
+	happiness					INT ,
+	h_change					INT ,
+	income						BIGINT ,
+	upkeep						BIGINT ,
+	specific_mining_settings	BOOLEAN ,
+	can_rename					BOOLEAN ,
+	can_abandon					BOOLEAN ,
+	abandon_time				INT
 );
 
 
@@ -243,26 +245,33 @@ GRANT EXECUTE ON FUNCTION verse.get_orbital_view( INT , INT ) TO :dbuser;
 --	an owner planet view entry
 --
 
+DROP FUNCTION IF EXISTS verse.get_owner_view( INT , INT ) CASCADE;
 CREATE OR REPLACE FUNCTION verse.get_owner_view( e_id INT , p_id INT )
-		RETURNS planet_owner_data
+		RETURNS emp.planet_owner_data
 		STRICT STABLE
 		SECURITY DEFINER
 	AS $$
 DECLARE
-	rv		planet_owner_data;
+	rv		emp.planet_owner_data;
 	t_happ	INT;
 	h_chg	INT;
 	mdelay	BIGINT;
 	r_time	INTERVAL;
 BEGIN
 	-- Get income, upkeep, current and target happiness
-	SELECT INTO rv.income , rv.upkeep , rv.happiness , t_happ
+	SELECT INTO rv.income , rv.upkeep , rv.happiness , t_happ , rv.specific_mining_settings
 			floor( pm.income )::INT , floor( pm.upkeep )::INT ,
 			floor( 100 * ph.current / p.population )::INT ,
-			floor( 100 * ph.target )::INT
+			floor( 100 * ph.target )::INT ,
+			_count.settings_exist
 		FROM verse.planets p
 			INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
 			INNER JOIN verse.planet_money pm ON pm.planet_id = p.name_id
+			CROSS JOIN (
+				SELECT ( COUNT( * ) > 0 ) AS settings_exist
+					FROM emp.planet_mining_settings
+					WHERE planet_id = p_id AND empire_id = e_id
+			) _count
 		WHERE p.name_id = p_id;
 
 	-- Compute happiness change indicator
@@ -306,7 +315,12 @@ BEGIN
 END;
 $$ LANGUAGE plpgsql;
 
-GRANT EXECUTE ON FUNCTION verse.get_owner_view( INT , INT ) TO :dbuser;
+REVOKE EXECUTE
+	ON FUNCTION verse.get_owner_view( INT , INT )
+	FROM PUBLIC;
+GRANT EXECUTE
+	ON FUNCTION verse.get_owner_view( INT , INT )
+	TO :dbuser;
 
 
 
diff --git a/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/015-mset-update-start-planet.sql b/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/015-mset-update-start-planet.sql
index 31536c8..fa25e41 100644
--- a/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/015-mset-update-start-planet.sql
+++ b/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/015-mset-update-start-planet.sql
@@ -22,7 +22,7 @@ BEGIN;
 		VALUES ( _get_emp_name( 'testEmp1' ) , 	_get_map_name( 'testPlanet3' ) );
 
 	/***** TESTS BEGIN HERE *****/
-	SELECT plan( 14 );
+	SELECT plan( 16 );
 
 	SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on bad empire identifier' );
 	SELECT ok( NOT emp.mset_update_start( _get_bad_emp_name( ) , _get_map_name( 'testPlanet1' ) ) );
@@ -55,7 +55,17 @@ BEGIN;
 	DROP TABLE IF EXISTS mset_update;
 
 	
-	SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on valid identifiers' );
+	SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on valid identifiers but no existing settings' );
+	SELECT ok( NOT emp.mset_update_start( _get_emp_name( 'testEmp1' ) , _get_map_name( 'testPlanet1' ) ) );
+	SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists despite lack of settings' );
+	SELECT has_table( 'mset_update' );
+	DROP TABLE IF EXISTS mset_update;
+
+	INSERT INTO emp.planet_mining_settings( empire_id , planet_id , resource_name_id )
+		SELECT _get_emp_name( 'testEmp1' ) , planet_id , resource_name_id
+			FROM verse.resource_providers
+			WHERE planet_id = _get_map_name( 'testPlanet1' );
+	SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on valid identifiers and existing settings' );
 	SELECT ok( emp.mset_update_start( _get_emp_name( 'testEmp1' ) , _get_map_name( 'testPlanet1' ) ) );
 	SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists' );
 	SELECT has_table( 'mset_update' );
diff --git a/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/040-mset-toggle-source.sql b/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/040-mset-toggle-source.sql
new file mode 100644
index 0000000..1765070
--- /dev/null
+++ b/legacyworlds-server-data/db-structure/tests/admin/040-functions/045-empire-mining/040-mset-toggle-source.sql
@@ -0,0 +1,61 @@
+/*
+ * Test the emp.mset_toggle_source( INT , INT ) function
+ */
+BEGIN;
+	/*
+	 * Create a pair of natural resources, three planets, an empire owning two
+	 * of the planets, and resource providers for one of the resources on the
+	 * neutral planet and on one of the owned planets.
+	 */
+	\i utils/strings.sql
+	\i utils/resources.sql
+	\i utils/accounts.sql
+	\i utils/naming.sql
+	\i utils/universe.sql
+	SELECT _create_natural_resources( 2 , 'resource' );
+	SELECT _create_raw_planets( 3 , 'planet' );
+	SELECT _create_emp_names( 1 , 'empire' );
+	SELECT emp.create_empire( _get_emp_name( 'empire1' ) ,
+				_get_map_name( 'planet1' ) ,
+				200.0 );
+	SELECT _create_resource_provider( 'planet1' , 'resource1' );
+	SELECT _create_resource_provider( 'planet2' , 'resource1' );
+	INSERT INTO emp.planets ( empire_id , planet_id )
+		VALUES ( _get_emp_name( 'empire1' ) , 	_get_map_name( 'planet3' ) );
+
+
+	-- ***** TESTS BEGIN HERE *****
+	SELECT plan( 8 );
+	
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Return value on bad empire identifier' );
+	SELECT ok( NOT emp.mset_toggle_source( _get_bad_emp_name( ) , _get_map_name( 'planet1' ) ) );
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Return value on bad planbet identifier' );
+	SELECT ok( NOT emp.mset_toggle_source( _get_emp_name( 'empire1' ) , _get_bad_map_name( ) ) );
+
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Return value when the empire does not own the planet' );
+	SELECT ok( NOT emp.mset_toggle_source( _get_emp_name( 'empire1' ) , _get_map_name( 'planet2' ) ) );
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Return value when the planet has no resource providers' );
+	SELECT ok( NOT emp.mset_toggle_source( _get_emp_name( 'empire1' ) , _get_map_name( 'planet3' ) ) );
+
+	DELETE FROM emp.planet_mining_settings;
+	UPDATE emp.mining_settings
+		SET empmset_weight = 0;
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Return value when activating' );
+	SELECT ok( emp.mset_toggle_source( _get_emp_name( 'empire1' ) , _get_map_name( 'planet1' ) ) );
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Mining settings inserted after activation' );
+	SELECT set_eq(
+		$$ SELECT * FROM emp.planet_mining_settings $$ ,
+		$$ VALUES ( _get_emp_name( 'empire1' ) , _get_map_name( 'planet1' ) , _get_string( 'resource1' ) , 0 ) $$
+	);
+
+	DELETE FROM emp.planet_mining_settings;
+	INSERT INTO emp.planet_mining_settings VALUES (
+		_get_emp_name( 'empire1' ) , _get_map_name( 'planet1' ) , _get_string( 'resource1' ) , 2
+	);
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Return value when de-activating' );
+	SELECT ok( emp.mset_toggle_source( _get_emp_name( 'empire1' ) , _get_map_name( 'planet1' ) ) );
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Mining settings deleted after de-activation' );
+	SELECT is_empty( $$ SELECT * FROM emp.planet_mining_settings $$ );
+
+	SELECT * FROM finish( );
+ROLLBACK;
\ No newline at end of file
diff --git a/legacyworlds-server-data/db-structure/tests/user/040-functions/045-empire-mining/040-mset-toggle-source.sql b/legacyworlds-server-data/db-structure/tests/user/040-functions/045-empire-mining/040-mset-toggle-source.sql
new file mode 100644
index 0000000..fcb9e61
--- /dev/null
+++ b/legacyworlds-server-data/db-structure/tests/user/040-functions/045-empire-mining/040-mset-toggle-source.sql
@@ -0,0 +1,15 @@
+/*
+ * Test privileges on emp.mset_toggle_source( INT , INT )
+ */
+BEGIN;
+	SELECT emp.mset_update_start( 1 );
+
+	SELECT plan( 1 );
+	
+	SELECT diag_test_name( 'emp.mset_toggle_source() - Privileges' );
+	SELECT lives_ok( $$
+			SELECT emp.mset_toggle_source( 1 , 1 )
+		$$ );
+	
+	SELECT * FROM finish( );
+ROLLBACK;
\ No newline at end of file
diff --git a/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/PlanetData.java b/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/PlanetData.java
index 1b47231..4200a91 100644
--- a/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/PlanetData.java
+++ b/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/PlanetData.java
@@ -22,7 +22,7 @@ public final class PlanetData
 
 		public AccessType getAccess( )
 		{
-			return access;
+			return this.access;
 		}
 
 
@@ -34,7 +34,7 @@ public final class PlanetData
 
 		public int getX( )
 		{
-			return x;
+			return this.x;
 		}
 
 
@@ -46,7 +46,7 @@ public final class PlanetData
 
 		public int getY( )
 		{
-			return y;
+			return this.y;
 		}
 
 
@@ -58,7 +58,7 @@ public final class PlanetData
 
 		public int getOrbit( )
 		{
-			return orbit;
+			return this.orbit;
 		}
 
 
@@ -70,7 +70,7 @@ public final class PlanetData
 
 		public int getPicture( )
 		{
-			return picture;
+			return this.picture;
 		}
 
 
@@ -82,7 +82,7 @@ public final class PlanetData
 
 		public String getName( )
 		{
-			return name;
+			return this.name;
 		}
 
 
@@ -94,7 +94,7 @@ public final class PlanetData
 
 		public String getTag( )
 		{
-			return tag;
+			return this.tag;
 		}
 
 
@@ -117,7 +117,7 @@ public final class PlanetData
 
 		public long getPopulation( )
 		{
-			return population;
+			return this.population;
 		}
 
 
@@ -129,7 +129,7 @@ public final class PlanetData
 
 		public long getDefence( )
 		{
-			return defence;
+			return this.defence;
 		}
 
 
@@ -141,7 +141,7 @@ public final class PlanetData
 
 		public long getOwnPower( )
 		{
-			return ownPower;
+			return this.ownPower;
 		}
 
 
@@ -153,7 +153,7 @@ public final class PlanetData
 
 		public long getFriendlyPower( )
 		{
-			return friendlyPower;
+			return this.friendlyPower;
 		}
 
 
@@ -165,7 +165,7 @@ public final class PlanetData
 
 		public long getHostilePower( )
 		{
-			return hostilePower;
+			return this.hostilePower;
 		}
 
 
@@ -177,7 +177,7 @@ public final class PlanetData
 
 		public Long getBattle( )
 		{
-			return battle;
+			return this.battle;
 		}
 
 
@@ -197,11 +197,12 @@ public final class PlanetData
 		private boolean renamePossible;
 		private boolean abandonPossible;
 		private Integer abandonTime;
+		private boolean ownSettings;
 
 
 		public int getHappiness( )
 		{
-			return happiness;
+			return this.happiness;
 		}
 
 
@@ -213,7 +214,7 @@ public final class PlanetData
 
 		public int gethChange( )
 		{
-			return hChange;
+			return this.hChange;
 		}
 
 
@@ -225,7 +226,7 @@ public final class PlanetData
 
 		public long getIncome( )
 		{
-			return income;
+			return this.income;
 		}
 
 
@@ -237,7 +238,7 @@ public final class PlanetData
 
 		public long getUpkeep( )
 		{
-			return upkeep;
+			return this.upkeep;
 		}
 
 
@@ -249,7 +250,7 @@ public final class PlanetData
 
 		public boolean isRenamePossible( )
 		{
-			return renamePossible;
+			return this.renamePossible;
 		}
 
 
@@ -261,7 +262,7 @@ public final class PlanetData
 
 		public boolean isAbandonPossible( )
 		{
-			return abandonPossible;
+			return this.abandonPossible;
 		}
 
 
@@ -273,7 +274,7 @@ public final class PlanetData
 
 		public Integer getAbandonTime( )
 		{
-			return abandonTime;
+			return this.abandonTime;
 		}
 
 
@@ -282,6 +283,18 @@ public final class PlanetData
 			this.abandonTime = abandonTime;
 		}
 
+
+		public boolean isOwnSettings( )
+		{
+			return this.ownSettings;
+		}
+
+
+		public void setOwnSettings( boolean ownSettings )
+		{
+			this.ownSettings = ownSettings;
+		}
+
 	}
 
 
diff --git a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/MiningSettingsDAO.java b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/MiningSettingsDAO.java
index c19656e..4281198 100644
--- a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/MiningSettingsDAO.java
+++ b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/MiningSettingsDAO.java
@@ -20,12 +20,30 @@ public interface MiningSettingsDAO
 	 * Start an empire settings update by calling the <code>emp.mset_update_start(INT)</code> stored
 	 * procedure.
 	 * 
-	 * @param empireId
+	 * @param empire
 	 *            the identifier of the empire whose settings will be updated
 	 * 
 	 * @return <code>true</code> on success, <code>false</code> on failure
 	 */
-	public boolean startUpdate( int empireId );
+	public boolean startUpdate( int empire );
+
+
+	/**
+	 * Start a planet settings update
+	 * 
+	 * <p>
+	 * Start a planet settings update by calling the <code>emp.mset_update_start(INT,INT)</code>
+	 * stored procedure.
+	 * 
+	 * @param empire
+	 *            the identifier of the empire who supposedly owns the planet
+	 * @param planet
+	 *            the identifier of the planet whose settings will be changed
+	 * 
+	 * @return <code>true</code> if the planet belongs to the specified empire and has specific
+	 *         mining settings
+	 */
+	public boolean startUpdate( int empire , int planet );
 
 
 	/**
@@ -57,4 +75,19 @@ public interface MiningSettingsDAO
 	 *         invalid.
 	 */
 	public boolean applyUpdate( );
+
+
+	/**
+	 * Toggle the source of a planet's mining settings
+	 * 
+	 * <p>
+	 * Call the <code>emp.mset_toggle_source(INT,INT)</code> stored procedure to toggle the source
+	 * of a planet's mining priorities.
+	 * 
+	 * @param empire
+	 *            the empire's identifier
+	 * @param planet
+	 *            the planet's identifier
+	 */
+	public void togglePlanet( int empire , int planet );
 }
diff --git a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/ResourcesController.java b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/ResourcesController.java
index 2444da7..940dc45 100644
--- a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/ResourcesController.java
+++ b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/game/resources/ResourcesController.java
@@ -27,4 +27,36 @@ public interface ResourcesController
 	 */
 	public void updateEmpireSettings( int empireId , Map< String , Integer > settings );
 
+
+	/**
+	 * Toggle the source of a planet's mining priorities
+	 * 
+	 * <p>
+	 * If the planet is currently using specific priorities, it will revert to empire-wide settings,
+	 * and vice-versa. The planet must belong to the specified empire.
+	 * 
+	 * @param empire
+	 *            the empire's identifier
+	 * @param planet
+	 *            the planet's identifier
+	 */
+	public void togglePlanet( int empire , int planet );
+
+
+	/**
+	 * Update a planet's mining settings
+	 * 
+	 * <p>
+	 * If the planet is using specific mining priorities and belongs to the specified empire, update
+	 * its mining priorities.
+	 * 
+	 * @param empire
+	 *            the empire's identifier
+	 * @param planet
+	 *            the planet's identifier
+	 * @param settings
+	 *            the new priorities
+	 */
+	public void updatePlanetSettings( int empire , int planet , Map< String , Integer > settings );
+
 }
diff --git a/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/MockMiningSettingsDAO.java b/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/MockMiningSettingsDAO.java
index 0b46dce..330c0f2 100644
--- a/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/MockMiningSettingsDAO.java
+++ b/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/MockMiningSettingsDAO.java
@@ -15,15 +15,27 @@ import com.deepclone.lw.interfaces.game.resources.MiningSettingsDAO;
 public class MockMiningSettingsDAO
 		implements MiningSettingsDAO
 {
-	/** The empire identifier with which {@link #startUpdate(int)} was called */
-	private Integer updateEmpire = null;
+	/**
+	 * The empire identifier with which {@link #startUpdate(int)} or {@link #togglePlanet(int, int)}
+	 * was called
+	 */
+	private Integer empire = null;
+
+	/** The planet identifier with which {@link #togglePlanet(int, int)} was called */
+	private Integer planet = null;
 
 	/** The amount of calls to {@link #setNewPriority(String, int)} */
 	private int callsToSet = 0;
 
+	/** Whether {@link #startUpdate(int)} was called */
+	private boolean startUpdateCalled = false;
+
 	/** Whether {@link #applyUpdate()} was called */
 	private boolean applyCalled = false;
 
+	/** Whether {@link #togglePlanet(int, int)} was called */
+	private boolean togglePlanetCalled = false;
+
 	/** Whether {@link #startUpdate(int)} will succeed or fail */
 	private boolean startUpdateSucceeds = true;
 
@@ -37,10 +49,24 @@ public class MockMiningSettingsDAO
 	private Integer maxSetCalls = null;
 
 
-	/** @return the empire identifier to update */
-	public Integer getUpdateEmpire( )
+	/** @return the empire identifier */
+	public Integer getEmpire( )
 	{
-		return this.updateEmpire;
+		return this.empire;
+	}
+
+
+	/** @return the planet identifier */
+	public Integer getPlanet( )
+	{
+		return this.planet;
+	}
+
+
+	/** @return <code>true</code> if {@link #startUpdate(int)()} was called */
+	public boolean wasStartUpdateCalled( )
+	{
+		return this.startUpdateCalled;
 	}
 
 
@@ -58,6 +84,13 @@ public class MockMiningSettingsDAO
 	}
 
 
+	/** @return <code>true</code> if {@link #togglePlanet(int, int)} was called */
+	public boolean wasTogllePlanetCalled( )
+	{
+		return this.togglePlanetCalled;
+	}
+
+
 	/**
 	 * Determine whether calls to {@link #startUpdate(int)} will succeed
 	 * 
@@ -98,7 +131,18 @@ public class MockMiningSettingsDAO
 	@Override
 	public boolean startUpdate( int empireId )
 	{
-		this.updateEmpire = empireId;
+		this.startUpdateCalled = true;
+		this.empire = empireId;
+		return this.startUpdateSucceeds;
+	}
+
+
+	@Override
+	public boolean startUpdate( int empire , int planet )
+	{
+		this.startUpdateCalled = true;
+		this.empire = empire;
+		this.planet = planet;
 		return this.startUpdateSucceeds;
 	}
 
@@ -118,4 +162,13 @@ public class MockMiningSettingsDAO
 		return this.applyUpdateSucceeds;
 	}
 
+
+	@Override
+	public void togglePlanet( int empire , int planet )
+	{
+		this.togglePlanetCalled = true;
+		this.empire = empire;
+		this.planet = planet;
+	}
+
 }
diff --git a/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/TestResourcesControllerBean.java b/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/TestResourcesControllerBean.java
index b836ab9..393b577 100644
--- a/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/TestResourcesControllerBean.java
+++ b/legacyworlds-server-tests/src/test/java/com/deepclone/lw/beans/game/resources/TestResourcesControllerBean.java
@@ -26,6 +26,9 @@ public class TestResourcesControllerBean
 	/** Empire identifier used in the tests */
 	private static final Integer EMPIRE_ID = 42;
 
+	/** Planet identifier used in the tests */
+	private static final Integer PLANET_ID = 43;
+
 	/** Mining settings used in the tests */
 	private static final Map< String , Integer > MINING_SETTINGS;
 
@@ -70,7 +73,25 @@ public class TestResourcesControllerBean
 	{
 		this.miningSettingsDAO.setStartUpdateSucceeds( false );
 		this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
-		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
+		assertTrue( this.miningSettingsDAO.wasStartUpdateCalled( ) );
+		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getEmpire( ) );
+		assertEquals( 0 , this.miningSettingsDAO.getCallsToSet( ) );
+		assertFalse( this.miningSettingsDAO.wasApplyCalled( ) );
+	}
+
+
+	/**
+	 * When calling {@link MiningSettingsDAO#startUpdate(int,int)} fails, the planet settings update
+	 * is interrupted.
+	 */
+	@Test
+	public void testPlanetStartUpdateFails( )
+	{
+		this.miningSettingsDAO.setStartUpdateSucceeds( false );
+		this.ctrl.updatePlanetSettings( EMPIRE_ID , PLANET_ID , MINING_SETTINGS );
+		assertTrue( this.miningSettingsDAO.wasStartUpdateCalled( ) );
+		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getEmpire( ) );
+		assertEquals( PLANET_ID , this.miningSettingsDAO.getPlanet( ) );
 		assertEquals( 0 , this.miningSettingsDAO.getCallsToSet( ) );
 		assertFalse( this.miningSettingsDAO.wasApplyCalled( ) );
 	}
@@ -85,7 +106,8 @@ public class TestResourcesControllerBean
 	{
 		this.miningSettingsDAO.setMaxSetCalls( 2 );
 		this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
-		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
+		assertTrue( this.miningSettingsDAO.wasStartUpdateCalled( ) );
+		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getEmpire( ) );
 		assertEquals( 3 , this.miningSettingsDAO.getCallsToSet( ) );
 		assertFalse( this.miningSettingsDAO.wasApplyCalled( ) );
 	}
@@ -100,7 +122,8 @@ public class TestResourcesControllerBean
 	public void testSettingsSuccess( )
 	{
 		this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
-		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
+		assertTrue( this.miningSettingsDAO.wasStartUpdateCalled( ) );
+		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getEmpire( ) );
 		assertEquals( 4 , this.miningSettingsDAO.getCallsToSet( ) );
 		assertTrue( this.miningSettingsDAO.wasApplyCalled( ) );
 	}
@@ -114,8 +137,21 @@ public class TestResourcesControllerBean
 	{
 		this.miningSettingsDAO.setApplyUpdateSucceeds( false );
 		this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
-		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
+		assertTrue( this.miningSettingsDAO.wasStartUpdateCalled( ) );
+		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getEmpire( ) );
 		assertEquals( 4 , this.miningSettingsDAO.getCallsToSet( ) );
 		assertTrue( this.miningSettingsDAO.wasApplyCalled( ) );
 	}
+
+	/**
+	 * "Toggle planet source" calls {@link MiningSettingsDAO#togglePlanet(int, int)}
+	 */
+	@Test
+	public void tesTogglePlanet()
+	{
+		this.ctrl.togglePlanet( EMPIRE_ID , PLANET_ID );
+		assertTrue( this.miningSettingsDAO.wasTogllePlanetCalled( ) );
+		assertEquals( EMPIRE_ID , this.miningSettingsDAO.getEmpire( ) );
+		assertEquals( PLANET_ID , this.miningSettingsDAO.getPlanet( ) );
+	}
 }
diff --git a/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/planets/ToggleMiningSettingsCommand.java b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/planets/ToggleMiningSettingsCommand.java
new file mode 100644
index 0000000..c15dc0e
--- /dev/null
+++ b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/planets/ToggleMiningSettingsCommand.java
@@ -0,0 +1,38 @@
+package com.deepclone.lw.cmd.player.planets;
+
+
+/**
+ * Command sent to toggle between empire-wide and planet-specific mining settings
+ * 
+ * <p>
+ * Sending this command to the server will try to switch between empire-wide and planet-specific
+ * settings on a given planet. The planet must be owned by the empire sending the command.
+ * 
+ * @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
+ */
+public class ToggleMiningSettingsCommand
+		extends ViewPlanetCommand
+{
+
+	/**
+	 * Serialisation version identifier
+	 * 
+	 * <ul>
+	 * <li>Introduced in B6M2 with ID 1.
+	 * </ul>
+	 */
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Initialise the command
+	 * 
+	 * @param planet
+	 *            the planet's identifier
+	 */
+	public ToggleMiningSettingsCommand( int planet )
+	{
+		super( planet );
+	}
+
+}
diff --git a/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/planets/UpdatePlanetMiningSettingsCommand.java b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/planets/UpdatePlanetMiningSettingsCommand.java
new file mode 100644
index 0000000..c29291c
--- /dev/null
+++ b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/planets/UpdatePlanetMiningSettingsCommand.java
@@ -0,0 +1,56 @@
+package com.deepclone.lw.cmd.player.planets;
+
+
+import java.util.Map;
+
+
+
+/**
+ * Command that updates a planet's mining settings
+ * 
+ * <p>
+ * This command must be sent with the identifier of a planet that belongs to the current empire. If
+ * the planet doesn't exist, if its ownership changed, or if it's configured to use empire-wide
+ * settings, the command will be ignored.
+ * 
+ * @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
+ */
+public class UpdatePlanetMiningSettingsCommand
+		extends ViewPlanetCommand
+{
+
+	/**
+	 * Serialisation version identifier
+	 * 
+	 * <ul>
+	 * <li>Introduced in B6M2 with ID 1
+	 * </ul>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/** The new mining settings */
+	private final Map< String , Integer > settings;
+
+
+	/**
+	 * Initialise the command using a planet identifier and mining settings
+	 * 
+	 * @param planet
+	 *            identifier of the planet to update 
+	 * @param settings
+	 *            a map that associates resource identifiers to priorities
+	 */
+	public UpdatePlanetMiningSettingsCommand( int planet , Map< String , Integer > settings )
+	{
+		super( planet );
+		this.settings = settings;
+	}
+
+
+	/** @return the mining settings to apply */
+	public Map< String , Integer > getSettings( )
+	{
+		return this.settings;
+	}
+
+}
diff --git a/legacyworlds-web-beans/src/main/java/com/deepclone/lw/web/csess/PlayerSession.java b/legacyworlds-web-beans/src/main/java/com/deepclone/lw/web/csess/PlayerSession.java
index 0f15268..6d132af 100644
--- a/legacyworlds-web-beans/src/main/java/com/deepclone/lw/web/csess/PlayerSession.java
+++ b/legacyworlds-web-beans/src/main/java/com/deepclone/lw/web/csess/PlayerSession.java
@@ -164,6 +164,36 @@ public class PlayerSession
 	}
 
 
+	/**
+	 * Send a {@link ToggleMiningSettingsCommand} to the server
+	 * 
+	 * @param pId
+	 *            the planet whose mining settings are to be switched between empire-wide and
+	 *            planet-specific
+	 */
+	public void toggleMiningSettingsFor( int pId )
+			throws SessionException , SessionServerException , SessionMaintenanceException
+	{
+		this.execute( new ToggleMiningSettingsCommand( pId ) );
+	}
+
+
+	/**
+	 * Send a {@link UpdatePlanetMiningSettingsCommand} to the server
+	 * 
+	 * @param pId
+	 *            the identifier of the planet to udpate
+	 * @param settings
+	 *            the map of settings, as associations between resource identifiers and priority
+	 *            values
+	 */
+	public void updatePlanetMiningSettings( int pId , Map< String , Integer > settings )
+			throws SessionException , SessionServerException , SessionMaintenanceException
+	{
+		this.execute( new UpdatePlanetMiningSettingsCommand( pId , settings ) );
+	}
+
+
 	public ViewPlanetResponse rename( int planetId , String name )
 			throws SessionException , SessionServerException , SessionMaintenanceException
 	{
diff --git a/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet.ftl b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet.ftl
index 7f3649c..e6b735c 100644
--- a/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet.ftl
+++ b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet.ftl
@@ -376,55 +376,8 @@
 
 			</#if>
 			
-			<#list data.own.resources as resource>
-				<#if resource.resourceProvider?has_content>
-					<#local showResources=true>
-					<#break>
-				</#if>
-			</#list>
-			
-			<#if showResources?has_content>
-				<@tab id="natres" title="Natural resources">
-				
-					<@listview>
-						<@lv_line headers=true>
-							<@lv_column width="x">Resource</@lv_column>
-							<@lv_column width=100 right=true>Quantity&nbsp;</@lv_column>
-							<@lv_column width=100>&nbsp;&nbsp;Capacity</@lv_column>
-							<@lv_column width=100 centered=true>Extraction<br/>difficulty</@lv_column>
-							<@lv_column width=100 centered=true>Priority</@lv_column>
-						</@lv_line>
-						
-						<#list data.own.resources as resource>
-							<#if resource.resourceProvider?has_content>
-								<#local resProv=resource.resourceProvider>
-
-								<@lv_line>
-									<@lv_column>
-										${resource.title?xhtml}
-										<div class="auto-hide">${resource.description?xhtml}</div>
-									</@lv_column>
-									<@lv_column right=true>${resProv.quantity?string(",##0")}&nbsp;</@lv_column>
-									<@lv_column>/&nbsp;${resProv.capacity?string(",##0")}</@lv_column>
-									<@lv_column centered=true>${resProv.difficulty}&nbsp;%</@lv_column>
-									<@lv_column centered=true>
-										<#switch resProv.priority>
-											<#case 0>lowest<#break>
-											<#case 1>low<#break>
-											<#case 2>normal<#break>
-											<#case 3>high<#break>
-											<#case 4>highest<#break>
-										</#switch>
-									</@lv_column>
-								</@lv_line>
-
-							</#if>
-						</#list>
-					</@listview>
-
-				</@tab>
-			</#if>
-
+			<#include "planet/natres.ftl" />
+			<@RenderNaturalResources />
 		</#if>
 		
 	</@tabs>
diff --git a/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet/natres.ftl b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet/natres.ftl
new file mode 100644
index 0000000..b110914
--- /dev/null
+++ b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/en/types/planet/natres.ftl
@@ -0,0 +1,79 @@
+<#macro RenderNaturalResources>			
+	<#list data.own.resources as resource>
+		<#if resource.resourceProvider?has_content>
+			<#local showResources=true>
+			<#break>
+		</#if>
+	</#list>
+	
+	<#if showResources?has_content>
+		<@tab id="natres" title="Natural resources">
+			<form action="planet-${data.id}-update-mset.action" method="POST">
+
+				<@listview>
+					<@lv_line headers=true>
+						<@lv_column width="x">Resource</@lv_column>
+						<@lv_column width=100 right=true>Quantity&nbsp;</@lv_column>
+						<@lv_column width=100>&nbsp;&nbsp;Capacity</@lv_column>
+						<@lv_column width=100 centered=true>Extraction<br/>difficulty</@lv_column>
+						<@lv_column width=100 centered=true>Priority</@lv_column>
+					</@lv_line>
+					
+					<#list data.own.resources as resource>
+						<#if resource.resourceProvider?has_content>
+							<#local resProv=resource.resourceProvider>
+		
+							<@lv_line>
+								<@lv_column>
+									${resource.title?xhtml}
+									<div class="auto-hide">${resource.description?xhtml}</div>
+								</@lv_column>
+								<@lv_column right=true>${resProv.quantity?string(",##0")}&nbsp;</@lv_column>
+								<@lv_column>/&nbsp;${resProv.capacity?string(",##0")}</@lv_column>
+								<@lv_column centered=true>${resProv.difficulty}&nbsp;%</@lv_column>
+								<@lv_column centered=true>
+									<#if data.own.ownMiningSettings>
+										<select name="pms-${resource.identifier?xhtml}" class="input">
+											<option style="padding: 0 5px" value="0" <#if resProv.priority = 0>selected="selected"</#if>>lowest</option>
+											<option style="padding: 0 5px" value="1" <#if resProv.priority = 1>selected="selected"</#if>>low</option>
+											<option style="padding: 0 5px" value="2" <#if resProv.priority = 2>selected="selected"</#if>>normal</option>
+											<option style="padding: 0 5px" value="3" <#if resProv.priority = 3>selected="selected"</#if>>high</option>
+											<option style="padding: 0 5px" value="4" <#if resProv.priority = 4>selected="selected"</#if>>highest</option>
+										</select>
+									<#else>
+										<#switch resProv.priority>
+											<#case 0>lowest<#break>
+											<#case 1>low<#break>
+											<#case 2>normal<#break>
+											<#case 3>high<#break>
+											<#case 4>highest<#break>
+										</#switch>
+									</#if>
+								</@lv_column>
+							</@lv_line>
+		
+						</#if>
+					</#list>
+					
+					<@lv_line headers=true>
+						<@lv_column width="x" colspan=5>&nbsp;</@lv_column>
+					</@lv_line>
+					<@lv_line>
+						<@lv_column right=true colspan=5>
+							<#if data.own.ownMiningSettings>
+								Using planet-specific settings
+								<input type="submit" name="toggle-settings" value="Use empire settings" class="input" style="margin: 15px 0 0 0" />
+								<input type="submit" name="update-pms" value="Update priorities" class="input" style="margin: 15px 0 0 0" />
+							<#else>
+								<input type="submit" name="toggle-settings" value="Use specific settings" class="input" style="margin: 15px 0 0 0" />
+							</#if>
+						</@lv_column>
+					</@lv_line>
+
+				</@listview>
+
+			</form>
+
+		</@tab>
+	</#if>
+</#macro>
\ No newline at end of file
diff --git a/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet.ftl b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet.ftl
index 5f6fadd..9c69b05 100644
--- a/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet.ftl
+++ b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet.ftl
@@ -374,54 +374,8 @@
 				</@tab>
 			</#if>
 
-			<#list data.own.resources as resource>
-				<#if resource.resourceProvider?has_content>
-					<#local showResources=true>
-					<#break>
-				</#if>
-			</#list>
-			
-			<#if showResources?has_content>
-				<@tab id="natres" title="Ressources naturelles">
-				
-					<@listview>
-						<@lv_line headers=true>
-							<@lv_column width="x">Ressource</@lv_column>
-							<@lv_column width=100 right=true>Quantité&nbsp;</@lv_column>
-							<@lv_column width=100>&nbsp;&nbsp;Capacité</@lv_column>
-							<@lv_column width=100 centered=true>Difficulté<br/>d'extraction</@lv_column>
-							<@lv_column width=100 centered=true>Priorité</@lv_column>
-						</@lv_line>
-						
-						<#list data.own.resources as resource>
-							<#if resource.resourceProvider?has_content>
-								<#local resProv=resource.resourceProvider>
-
-								<@lv_line>
-									<@lv_column>
-										${resource.title?xhtml}
-										<div class="auto-hide">${resource.description?xhtml}</div>
-									</@lv_column>
-									<@lv_column right=true>${resProv.quantity?string(",##0")}&nbsp;</@lv_column>
-									<@lv_column>/&nbsp;${resProv.capacity?string(",##0")}</@lv_column>
-									<@lv_column centered=true>${resProv.difficulty}&nbsp;%</@lv_column>
-									<@lv_column centered=true>
-										<#switch resProv.priority>
-											<#case 0>très basse<#break>
-											<#case 1>basse<#break>
-											<#case 2>normale<#break>
-											<#case 3>haute<#break>
-											<#case 4>très haute<#break>
-										</#switch>
-									</@lv_column>
-								</@lv_line>
-
-							</#if>
-						</#list>
-					</@listview>
-
-				</@tab>
-			</#if>
+			<#include "planet/natres.ftl" />
+			<@RenderNaturalResources />
 
 		</#if>
 
diff --git a/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet/natres.ftl b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet/natres.ftl
new file mode 100644
index 0000000..2f30d41
--- /dev/null
+++ b/legacyworlds-web-main/Content/Raw/WEB-INF/fm/fr/types/planet/natres.ftl
@@ -0,0 +1,80 @@
+<#macro RenderNaturalResources>			
+	<#list data.own.resources as resource>
+		<#if resource.resourceProvider?has_content>
+			<#local showResources=true>
+			<#break>
+		</#if>
+	</#list>
+	
+	<#if showResources?has_content>
+				<@tab id="natres" title="Ressources naturelles">
+			<form action="planet-${data.id}-update-mset.action" method="POST">
+
+				<@listview>
+					<@lv_line headers=true>
+						<@lv_column width="x">Ressource</@lv_column>
+						<@lv_column width=100 right=true>Quantité&nbsp;</@lv_column>
+						<@lv_column width=100>&nbsp;&nbsp;Capacité</@lv_column>
+						<@lv_column width=100 centered=true>Difficulté<br/>d'extraction</@lv_column>
+						<@lv_column width=100 centered=true>Priorité</@lv_column>
+					</@lv_line>
+					
+					<#list data.own.resources as resource>
+						<#if resource.resourceProvider?has_content>
+							<#local resProv=resource.resourceProvider>
+		
+							<@lv_line>
+								<@lv_column>
+									${resource.title?xhtml}
+									<div class="auto-hide">${resource.description?xhtml}</div>
+								</@lv_column>
+								<@lv_column right=true>${resProv.quantity?string(",##0")}&nbsp;</@lv_column>
+								<@lv_column>/&nbsp;${resProv.capacity?string(",##0")}</@lv_column>
+								<@lv_column centered=true>${resProv.difficulty}&nbsp;%</@lv_column>
+								<@lv_column centered=true>
+									<#if data.own.ownMiningSettings>
+										<select name="pms-${resource.identifier?xhtml}" class="input">
+											<option style="padding: 0 5px" value="0" <#if resProv.priority = 0>selected="selected"</#if>>très basse</option>
+											<option style="padding: 0 5px" value="1" <#if resProv.priority = 1>selected="selected"</#if>>basse</option>
+											<option style="padding: 0 5px" value="2" <#if resProv.priority = 2>selected="selected"</#if>>normale</option>
+											<option style="padding: 0 5px" value="3" <#if resProv.priority = 3>selected="selected"</#if>>haute</option>
+											<option style="padding: 0 5px" value="4" <#if resProv.priority = 4>selected="selected"</#if>>très haute</option>
+										</select>
+									<#else>
+										<#switch resProv.priority>
+											<#case 0>très basse<#break>
+											<#case 1>basse<#break>
+											<#case 2>normale<#break>
+											<#case 3>haute<#break>
+											<#case 4>très haute<#break>
+										</#switch>
+									</#if>
+								</@lv_column>
+							</@lv_line>
+		
+						</#if>
+					</#list>
+					
+					<@lv_line headers=true>
+						<@lv_column width="x" colspan=5>&nbsp;</@lv_column>
+					</@lv_line>
+					<@lv_line>
+						<@lv_column right=true colspan=5>
+							<#if data.own.ownMiningSettings>
+								Cette planète utilise des priorités d'extraction qui lui sont spécifiques.
+								<input type="submit" name="toggle-settings" value="Utiliser les priorités de l'empire" class="input" style="margin: 15px 0 0 0" />
+								<input type="submit" name="update-pms" value="Mettre à jour les priorités" class="input" style="margin: 15px 0 0 0" />
+							<#else>
+								Cette planète utilise les priorités d'extraction de l'empire.
+								<input type="submit" name="toggle-settings" value="Utiliser des priorités spécifiques" class="input" style="margin: 15px 0 0 0" />
+							</#if>
+						</@lv_column>
+					</@lv_line>
+
+				</@listview>
+
+			</form>
+
+		</@tab>
+	</#if>
+</#macro>
\ No newline at end of file
diff --git a/legacyworlds-web-main/src/main/java/com/deepclone/lw/web/main/game/PlanetPage.java b/legacyworlds-web-main/src/main/java/com/deepclone/lw/web/main/game/PlanetPage.java
index e0afc3c..2bbb419 100644
--- a/legacyworlds-web-main/src/main/java/com/deepclone/lw/web/main/game/PlanetPage.java
+++ b/legacyworlds-web-main/src/main/java/com/deepclone/lw/web/main/game/PlanetPage.java
@@ -1,6 +1,10 @@
 package com.deepclone.lw.web.main.game;
 
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
 import javax.servlet.http.HttpServletRequest;
 
 import org.springframework.stereotype.Controller;
@@ -80,8 +84,8 @@ public class PlanetPage
 
 
 	@RequestMapping( value = "/planet-{planetId}-cancel-abandon.action" , method = RequestMethod.POST )
-	public String cancelAbandon( HttpServletRequest request , @ModelAttribute( "language" ) String language , Model model ,
-			@PathVariable String planetId )
+	public String cancelAbandon( HttpServletRequest request , @ModelAttribute( "language" ) String language ,
+			Model model , @PathVariable String planetId )
 			throws SessionException , SessionServerException , SessionMaintenanceException
 	{
 		int pId;
@@ -233,4 +237,108 @@ public class PlanetPage
 		PlayerSession pSession = this.getSession( PlayerSession.class , request );
 		return this.render( model , "game" , language , "planet" , pSession.flushQueue( pId , true ) );
 	}
+
+
+	/**
+	 * Handler for commands that modify planet mining settings
+	 * 
+	 * <p>
+	 * This method handles all mining settings commands, including both switching between empire-
+	 * and planet-specific settings and updating all priorities.
+	 * 
+	 * @param request
+	 *            the HTTP request
+	 * @param model
+	 *            the model
+	 * @param planetId
+	 *            the planet's identifier string from the path
+	 * @param toggle
+	 *            this parameter from the form's <code>toggle-settings</code> value will be set if
+	 *            the "Switch to empire-wide/planet-specific settings" button was clicked.
+	 * 
+	 * @return a redirect to the overview page if the planet identifier was invalid, or a redirect
+	 *         to the planet page's natural resources tab otherwise.
+	 * 
+	 * @throws SessionException
+	 *             if some error occurs on the server
+	 * @throws SessionServerException
+	 *             if the server is unreachable
+	 * @throws SessionMaintenanceException
+	 *             if the game is under maintenance
+	 */
+	@RequestMapping( value = "/planet-{planetId}-update-mset.action" , method = RequestMethod.POST )
+	public String updateMiningSettings( HttpServletRequest request , Model model , @PathVariable String planetId ,
+			@RequestParam( value = "toggle-settings" , required = false ) String toggle )
+			throws SessionException , SessionServerException , SessionMaintenanceException
+	{
+		int pId;
+		try {
+			pId = Integer.parseInt( planetId );
+		} catch ( NumberFormatException e ) {
+			return this.redirect( "overview" );
+		}
+
+		PlayerSession session = this.getSession( PlayerSession.class , request );
+		if ( toggle == null ) {
+			Map< String , Integer > settings = this.getMiningSettings( request );
+			if ( settings != null ) {
+				session.updatePlanetMiningSettings( pId , settings );
+			}
+		} else {
+			session.toggleMiningSettingsFor( pId );
+		}
+
+		return this.redirect( "planet-" + Integer.toString( pId ) + "#natres" );
+	}
+
+
+	/**
+	 * Extract mining priorities from the HTTP request
+	 * 
+	 * <p>
+	 * Look for all submitted fields that begin with "pms-" then try to extract their values into a
+	 * map that associates resource identifiers to priorities.
+	 * 
+	 * @param request
+	 *            the HTTP request
+	 * 
+	 * @return the map containing the submitted mining settings, or <code>null</code> if one of the
+	 *         values was incorrect.
+	 */
+	private Map< String , Integer > getMiningSettings( HttpServletRequest request )
+	{
+		Map< String , Object > input = this.getInput( request );
+		Map< String , Integer > miningSettings = new HashMap< String , Integer >( );
+		for ( Entry< String , Object > entry : input.entrySet( ) ) {
+			// Ignore items which are not mining settings
+			String name = entry.getKey( );
+			if ( !name.startsWith( "pms-" ) ) {
+				continue;
+			}
+			name = name.substring( 4 );
+
+			// Get values
+			if ( ! ( entry.getValue( ) instanceof String[] ) ) {
+				continue;
+			}
+			String[] values = (String[]) entry.getValue( );
+			if ( values.length < 1 ) {
+				continue;
+			}
+
+			// Pre-validate them
+			int value;
+			try {
+				value = Integer.parseInt( values[ 0 ] );
+			} catch ( NumberFormatException e ) {
+				value = -1;
+			}
+			if ( value < 0 || value > 4 ) {
+				return null;
+			}
+
+			miningSettings.put( name , value );
+		}
+		return miningSettings;
+	}
 }