我正在製作一個遊戲,玩家必須編寫自己的課程來控制屏幕上的單位。但是,我想阻止他們在播放器類中使用靜態變量,以便他們的單元必須通過我開發的通信系統(即傳輸1s和0s)來傳遞信息,而不是隻訪問靜態「unitsTargeted」變量或任何其他地方有可能。我可以阻止他們以某種方式使用靜態修飾符嗎?防止使用靜態修飾符
回答
這取決於。如果你無法控制源代碼或運行環境,那麼你不能阻止它們編譯他們想要的東西或執行它。
如果您可以控制構建(即:將源發送到您控制的系統並控制編譯),那麼您可以構建自定義編譯器。
如果您以某種方式控制運行環境,則可以檢查提供的類以查看其中包含的內容。你可以使用一些字節碼工具,或者更好的是使用反射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
請注意,您在做什麼,可能是危險的並且應該非常小心地限制服務器端可以執行的代碼。所有需要做的事情都是爲了毀掉你的日子而提交的一個類,它會刪除文件或安裝不需要的文件或任何其他惡意行爲。
這聽起來像我需要做的。你能指出我對如何切實執行這個任何好的資源嗎?我的計劃是讓玩家通過網頁將他們的課程上傳到我控制的服務器,我的源代碼將運行遊戲並返回結果。所以我理論上應該能夠在運行源代碼之前檢查玩家是否使用了任何靜態變量。謝謝! –
不要在程序中使用靜態變量,或者如果您確實需要靜態變量,請將其設置爲ThreadLocal並將其保留在無法從用戶類訪問的線程中。
如果你希望你的程序比較安全,你還應該建立一些類驗證器來確保這些類只使用允許的類,一個很短的白名單允許的類。
您可以使用ASM來製作此類驗證程序。
謝謝,這聽起來像我需要做的事情。我會檢查ASM。 –
- 1. Objective-C修飾符用於靜態?
- 2. Eclipse JDT靜態字段修飾符
- 3. Java靜態修飾符查詢
- 4. 在「冗餘‘靜態’修飾符」警告
- 5. 理解靜態修飾符的問題
- 6. Java常量和靜態修飾符
- 7. 在C++中是靜態修飾符嗎?
- 8. 什麼時候在PHP中使用靜態修飾符
- 9. 創建EventHandler時使用靜態修飾符有什麼意義?
- 10. 訪問修飾符是否適用於靜態類函數?
- 11. 動態訪問修飾符
- 12. 帶靜態訪問修飾符的最終變量
- 13. 爲什麼在這段代碼中需要靜態修飾符?
- 14. 「導入」後的「靜態」修飾符是什麼意思?
- 15. java中有沒有對靜態塊的訪問修飾符
- 16. 在TypeScript的函數中使用靜態修飾符有什麼好處嗎?
- 17. 頂級類或接口是否可以使用「靜態」修飾符?
- 18. 在Java中如何以及在何處使用靜態修飾符?
- 19. __strong修飾符
- 20. __printflike__修飾符
- 21. '出' 修飾符
- 22. AtTask修飾符
- 23. preventDefault沒有阻止使用Alt修飾符的鍵
- 24. 國防部重寫 - 需要修改修飾符?
- 25. 動態方法訪問修飾符
- 26. 靜態修飾符在面向對象編程中的用途是什麼?
- 27. 防止進入靜態庫代碼
- 28. 防止Tomcat提供靜態資源
- 29. 防止靜態庫被初始化
- 30. 防止iisnode緩存require'd靜態文件
不是真的,除非你想編寫你自己的編譯器。 – shmosel
將行爲部分卸載到玩家必須實現的抽象類或接口。防止他們接觸玩家類。 – anacron
目前還不清楚爲什麼靜態變量在玩家類中無效。如果他們做一個非靜態的'unitsTargeted'變量會不會也不好? –