Don't turn off PVP.
What you want to do is create a modifier for the players to make them belong to a team. You could add a custom Capability that lists their Teamname for example.
Now what you want to do is create an forge event https://mcforge.readthedocs.io/en/latest/events/intro/
in which you subscribe to the LivingHurtEvent, this event fires whenever a player is ABOUT to take damage.
Now you make it only listen to players taking damage, you do this with a simple if statement.
if(event.getEntity() instanceof EntityPlayer)
Now you have an Event that will listen to the damage event. You can now use event.getSource() to get the damage source. Most damage sources in the game (Projectiles, sword attacks etc.) Will have a parameter that tells you who actually fired the arrow/used the sword.
While the code below probably wouldn't work, since I removed the part about capabilities with a comment and you probably need a few null checks to make sure the damagesource has an Entity attached. This is what I imagine the event would end up looking like:
@SubscribeEvent
public void event(LivingHurtEvent event){
if(event.getEntity() instanceof EntityPlayer && event.getSource().getSourceOfDamage() instanceof EntityPlayer){
EntityPlayer hitter = (EntityPlayer)event.getSource().getSourceOfDamage(); //returns an Entity who caused the damage.
EntityPlayer target = (EntityPlayer)event.getEntity(); //returns Entity who got hit. We already established this is a player.
//Code to check the user's Capabilities and see if they have the same team here
if(hitterCapability.getTeam == targetCapability.getTeam){
event.setCanceled(true);
}
}
}
now, adding capabilities to players is documented here: https://mcforge.readthedocs.io/en/latest/datastorage/capabilities/ and if you want to synch this up to the server side you probably want to use a packet, unless players don't get a team untill after they log in.
Sorry for being a bit long while talking, I'm messaging away from home.
I hope this helps a bit, if you have questions feel free to ask.
Edit: Not every source of damage has a player source like I said before, make sure that the code you end up making takes this into account. If the source of the damage is an TNT block you might want to block the damage alltogether. The most basic use of blocking damage with a player source should block sources like hits, throwables, throwing potions(?) etc.
But the things that are NOT blocked are mostly stuff with big AOE's, which means that that could possibly count as friendly fire when blowing stuff up.