2017-03-09 9 views
0

私は、プレイヤーが画面上のユニットをコントロールするために独自のクラスを作成する必要があるゲームを作っています。しかし、私はプレイヤークラス内でスタティック変数を使用しないようにして、スタティックな "unitsTargeted"変数や他のものにアクセスするのではなく、自分の開発した通信システム(つまり1と0を送信する)それは可能性があります。何らかの理由で静的修飾子を使用できないようにすることはできますか?スタティックモディファイアの使用を禁止する

+1

あなた自身のコンパイラを作成しない限り、実際にはありません。 – shmosel

+0

ビヘイビア部分を、プレーヤが実装する必要のある抽象クラスまたはインタフェースにオフロードします。それらがPlayersクラスに触れることを防ぎます。 – anacron

+0

'static'変数がプレーヤークラスで有効でない理由は不明です。それらが非静的な 'unitsTargeted'変数を作るなら、それは悪くないでしょうか? –

答えて

0

ソースコードや実行環境を制御できない場合、自分が望むものをコンパイルしたり実行したりすることを止めることはできません。

ビルドを制御できる場合(つまり、ソースが制御したシステムに送信され、コンパイルを制御する場合)、カスタムコンパイラをビルドできます。

実行環境を何らかの方法で制御する場合、提供されたクラスを調べて、含まれているものを確認することができます。いくつかのバイトコードツールを使用することもできますし、リフレクションAPIを使用してメンバーが静的であるかどうかを確認することもできます。リフレクションを使用してメンバーのリストを取得したら、それを反復してisStaticをチェックしてください。クラスに静的メンバーが含まれている場合は、それを拒否できます。

クライアントからクラスをサーバーにアップロードするため、JavaのリフレクションAPIを使用するだけで確認できます。クライアントがソースコードを提出している場合は、最初にコンパイルする必要がありますが、使用する前にそれを行うと仮定します。ここで

は、私はちょうど走ったテストケースである:

package test.tmp; 

import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
import java.util.ArrayList; 
import java.util.List; 

public class StaticChecker 
{ 
    public static void main(String[] args) 
    { 
     for(Class c : new Class[]{StaticChecker.class, ClassWithStatics.class, ClassWithoutStatics.class}) 
     { 
      System.out.println("For " + c + "..."); 

      boolean hasStatic = hasStaticMembers(c); 
      System.out.println("\tIt contains static members: " + hasStatic); 

      if(hasStatic) 
      { 
       System.out.println("\tThe static members are:"); 
       for(String s : checkStaticMembers(c)) 
        System.out.println("\t\t" + s); 
      } 
     } 
    } 

    public static boolean hasStaticMembers(Class c) 
    { 
     return checkStaticMembers(c).size() > 0; 
    } 

    public static List<String> checkStaticMembers(Class c) 
    { 
     List<String> staticMemberNames = new ArrayList<String>(); 

     for(Field field : c.getDeclaredFields()) 
      if(Modifier.isStatic(field.getModifiers())) 
       staticMemberNames.add(field.toString()); 

     for(Method method : c.getDeclaredMethods()) 
      if(Modifier.isStatic(method.getModifiers())) 
       staticMemberNames.add(method.toString()); 

     return staticMemberNames; 
    } 
} 

class ClassWithStatics 
{ 
    public static int N = 3; 
    private static String S = "?"; 

    private int n; 

    void f() { System.out.println("f()"); } 
    static void g() { System.out.println("g()"); } 
    public static void h() { System.out.println("h()"); } 
} 

class ClassWithoutStatics 
{ 
    int a; 
    String b; 
    void f() { System.out.println("f()"); } 
} 

私は上記のテストを実行すると、私は次のような出力が得られます。

For class test.tmp.StaticChecker... 
    It contains static members: true 
    The static members are: 
     public static void test.tmp.StaticChecker.main(java.lang.String[]) 
     public static java.util.List test.tmp.StaticChecker.checkStaticMembers(java.lang.Class) 
     public static boolean test.tmp.StaticChecker.hasStaticMembers(java.lang.Class) 
For class test.tmp.ClassWithStatics... 
    It contains static members: true 
    The static members are: 
     public static int test.tmp.ClassWithStatics.N 
     private static java.lang.String test.tmp.ClassWithStatics.S 
     static void test.tmp.ClassWithStatics.g() 
     public static void test.tmp.ClassWithStatics.h() 
For class test.tmp.ClassWithoutStatics... 
    It contains static members: false 

何をやっていることは危険なことができますのでご注意くださいサーバー側で実行できるコードを制限することには非常に注意が必要です。あなたの日を台無しにするために必要なのは、ファイルを削除したり、不要なファイルやその他の悪質な行為をインストールするクラスを提出することです。

+0

これは私がする必要があるように聞こえる。実際にこれを実装する方法に関して、私に良いリソースに向けて私を指摘できますか?私の計画は、プレイヤーがWebページを介してクラスを自分が管理しているサーバーにアップロードすることです。ソースコードがゲームを実行し、結果を返します。だから理論的には、プレイヤーがソースコードを実行する前に静的変数を使用しているかどうかを調べることができるはずです。ありがとう! –

0

プログラムで静的変数を使用しないでください。本当に必要な場合は、ThreadLocalを作成し、ユーザークラスからアクセスできないスレッドにその変数を保持してください。

あなたのプログラムが比較的安全であるようにするには、ある種のクラスバリデーターを作成して、許可されたクラスのみを使用するようにする必要があります。

ASMを使用して、このようなバリデータを作成できます。

+0

ありがとう、これは私がする必要があるもののように聞こえる。私はASMをチェックアウトします。 –

関連する問題