mirror of
https://git.krews.org/morningstar/Arcturus-Community.git
synced 2024-11-30 09:50:51 +01:00
Merge branch 'redeemable-clothing-fixes' into 'dev'
Prevent unredeemed clothing to be used by user See merge request morningstar/Arcturus-Community!34
This commit is contained in:
commit
43093feb2a
@ -17,4 +17,8 @@ INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('invisible.prevent.chat.err
|
|||||||
|
|
||||||
INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('commands.succes.cmd_invisible.updated.back', 'You are now visible again.');
|
INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('commands.succes.cmd_invisible.updated.back', 'You are now visible again.');
|
||||||
|
|
||||||
|
INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('commands.error.cmd_mimic.forbidden_clothing', 'The other user has clothing that you do not own yet.');
|
||||||
|
ALTER TABLE `permissions`
|
||||||
|
ADD COLUMN `acc_mimic_unredeemed` enum('0','1') NOT NULL DEFAULT '0';
|
||||||
|
|
||||||
#END DATABASE UPDATE: 2.0.0 RC-2 -> 2.0.0 RC-3
|
#END DATABASE UPDATE: 2.0.0 RC-2 -> 2.0.0 RC-3
|
||||||
|
@ -7,6 +7,7 @@ import com.eu.habbo.habbohotel.users.Habbo;
|
|||||||
import com.eu.habbo.habbohotel.users.HabboGender;
|
import com.eu.habbo.habbohotel.users.HabboGender;
|
||||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||||
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
|
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
|
||||||
|
import com.eu.habbo.util.figure.FigureUtil;
|
||||||
|
|
||||||
public class MimicCommand extends Command
|
public class MimicCommand extends Command
|
||||||
{
|
{
|
||||||
@ -18,28 +19,24 @@ public class MimicCommand extends Command
|
|||||||
@Override
|
@Override
|
||||||
public boolean handle(GameClient gameClient, String[] params) throws Exception
|
public boolean handle(GameClient gameClient, String[] params) throws Exception
|
||||||
{
|
{
|
||||||
if(params.length == 2)
|
if (params.length == 2) {
|
||||||
{
|
|
||||||
Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]);
|
Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]);
|
||||||
|
|
||||||
if (habbo == null)
|
if (habbo == null) {
|
||||||
{
|
|
||||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_found").replace("%user%", ""), RoomChatMessageBubbles.ALERT);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_found").replace("%user%", ""), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(habbo == gameClient.getHabbo())
|
if (habbo == gameClient.getHabbo()) {
|
||||||
{
|
|
||||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_self"), RoomChatMessageBubbles.ALERT);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_self"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if (habbo.hasPermission("acc_not_mimiced") && !gameClient.getHabbo().hasPermission("acc_not_mimiced")) {
|
||||||
else if(habbo.hasPermission("acc_not_mimiced") && !gameClient.getHabbo().hasPermission("acc_not_mimiced"))
|
|
||||||
{
|
|
||||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.blocked").replace("%user%", params[1]).replace("%gender_name%", (habbo.getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), RoomChatMessageBubbles.ALERT);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.blocked").replace("%user%", params[1]).replace("%gender_name%", (habbo.getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else if (!habbo.hasPermission("acc_mimic_unredeemed") && FigureUtil.hasBlacklistedClothing(habbo.getHabboInfo().getLook(), gameClient.getHabbo().getForbiddenClothing())) {
|
||||||
else
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.forbidden_clothing"), RoomChatMessageBubbles.ALERT);
|
||||||
{
|
return true;
|
||||||
|
} else {
|
||||||
gameClient.getHabbo().getHabboInfo().setLook(habbo.getHabboInfo().getLook());
|
gameClient.getHabbo().getHabboInfo().setLook(habbo.getHabboInfo().getLook());
|
||||||
gameClient.getHabbo().getHabboInfo().setGender(habbo.getHabboInfo().getGender());
|
gameClient.getHabbo().getHabboInfo().setGender(habbo.getHabboInfo().getGender());
|
||||||
gameClient.sendResponse(new UserDataComposer(gameClient.getHabbo()));
|
gameClient.sendResponse(new UserDataComposer(gameClient.getHabbo()));
|
||||||
|
@ -9,6 +9,7 @@ import com.eu.habbo.habbohotel.users.HabboItem;
|
|||||||
import com.eu.habbo.messages.ServerMessage;
|
import com.eu.habbo.messages.ServerMessage;
|
||||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||||
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
|
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
|
||||||
|
import com.eu.habbo.util.figure.FigureUtil;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -93,7 +94,7 @@ public class InteractionMannequin extends HabboItem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.getHabbo().getHabboInfo().setLook(look.substring(0, look.length() - 1));
|
client.getHabbo().getHabboInfo().setLook(look.substring(0, look.length() - 1), true);
|
||||||
room.sendComposer(new RoomUserDataComposer(client.getHabbo()).compose());
|
room.sendComposer(new RoomUserDataComposer(client.getHabbo()).compose());
|
||||||
client.sendResponse(new UserDataComposer(client.getHabbo()));
|
client.sendResponse(new UserDataComposer(client.getHabbo()));
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import com.eu.habbo.plugin.EventHandler;
|
|||||||
import com.eu.habbo.plugin.events.users.UserDisconnectEvent;
|
import com.eu.habbo.plugin.events.users.UserDisconnectEvent;
|
||||||
import com.eu.habbo.plugin.events.users.UserExitRoomEvent;
|
import com.eu.habbo.plugin.events.users.UserExitRoomEvent;
|
||||||
import com.eu.habbo.plugin.events.users.UserSavedLookEvent;
|
import com.eu.habbo.plugin.events.users.UserSavedLookEvent;
|
||||||
import com.eu.habbo.util.FigureUtil;
|
import com.eu.habbo.util.figure.FigureUtil;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -102,7 +102,7 @@ public class InteractionFootballGate extends HabboItem
|
|||||||
Emulator.getPluginManager().fireEvent(lookEvent);
|
Emulator.getPluginManager().fireEvent(lookEvent);
|
||||||
if(!lookEvent.isCancelled())
|
if(!lookEvent.isCancelled())
|
||||||
{
|
{
|
||||||
habbo.getHabboInfo().setLook(lookEvent.newLook);
|
habbo.getHabboInfo().setLook(lookEvent.newLook, true);
|
||||||
Emulator.getThreading().run(habbo.getHabboInfo());
|
Emulator.getThreading().run(habbo.getHabboInfo());
|
||||||
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
||||||
room.sendComposer(new RoomUserDataComposer(habbo).compose());
|
room.sendComposer(new RoomUserDataComposer(habbo).compose());
|
||||||
@ -119,7 +119,7 @@ public class InteractionFootballGate extends HabboItem
|
|||||||
if(!lookEvent.isCancelled())
|
if(!lookEvent.isCancelled())
|
||||||
{
|
{
|
||||||
habbo.getHabboStats().cache.put(CACHE_KEY, habbo.getHabboInfo().getLook());
|
habbo.getHabboStats().cache.put(CACHE_KEY, habbo.getHabboInfo().getLook());
|
||||||
habbo.getHabboInfo().setLook(lookEvent.newLook);
|
habbo.getHabboInfo().setLook(lookEvent.newLook, true);
|
||||||
Emulator.getThreading().run(habbo.getHabboInfo());
|
Emulator.getThreading().run(habbo.getHabboInfo());
|
||||||
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
||||||
room.sendComposer(new RoomUserDataComposer(habbo).compose());
|
room.sendComposer(new RoomUserDataComposer(habbo).compose());
|
||||||
|
@ -17,14 +17,15 @@ import com.eu.habbo.messages.outgoing.users.*;
|
|||||||
import com.eu.habbo.plugin.events.users.UserCreditsEvent;
|
import com.eu.habbo.plugin.events.users.UserCreditsEvent;
|
||||||
import com.eu.habbo.plugin.events.users.UserDisconnectEvent;
|
import com.eu.habbo.plugin.events.users.UserDisconnectEvent;
|
||||||
import com.eu.habbo.plugin.events.users.UserPointsEvent;
|
import com.eu.habbo.plugin.events.users.UserPointsEvent;
|
||||||
|
import gnu.trove.TIntCollection;
|
||||||
import gnu.trove.map.hash.THashMap;
|
import gnu.trove.map.hash.THashMap;
|
||||||
import gnu.trove.set.hash.THashSet;
|
import gnu.trove.set.hash.THashSet;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Map;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class Habbo implements Runnable
|
public class Habbo implements Runnable
|
||||||
{
|
{
|
||||||
@ -512,4 +513,14 @@ public class Habbo implements Runnable
|
|||||||
this.client.getHabbo().getHabboInfo().getCurrentRoom().unIdle(this.client.getHabbo());
|
this.client.getHabbo().getHabboInfo().getCurrentRoom().unIdle(this.client.getHabbo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Integer> getForbiddenClothing() {
|
||||||
|
TIntCollection clothingIDs = this.getInventory().getWardrobeComponent().getClothing();
|
||||||
|
|
||||||
|
return Emulator.getGameEnvironment().getCatalogManager().clothing.values().stream()
|
||||||
|
.filter(c -> !clothingIDs.contains(c.id))
|
||||||
|
.map(c -> c.setId)
|
||||||
|
.flatMap(c -> Arrays.stream(c).boxed())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import com.eu.habbo.habbohotel.rooms.RoomTile;
|
|||||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer;
|
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer;
|
||||||
import com.eu.habbo.threading.runnables.RoomUnitRidePet;
|
import com.eu.habbo.threading.runnables.RoomUnitRidePet;
|
||||||
|
import com.eu.habbo.util.figure.FigureUtil;
|
||||||
import gnu.trove.map.hash.TIntIntHashMap;
|
import gnu.trove.map.hash.TIntIntHashMap;
|
||||||
import gnu.trove.procedure.TIntIntProcedure;
|
import gnu.trove.procedure.TIntIntProcedure;
|
||||||
|
|
||||||
@ -215,7 +216,19 @@ public class HabboInfo implements Runnable
|
|||||||
return this.look;
|
return this.look;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLook(String look) { this.look = look; }
|
public void setLook(String look) {
|
||||||
|
this.setLook(look, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLook(String look, boolean stripForbidden) {
|
||||||
|
if (stripForbidden) {
|
||||||
|
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.id);
|
||||||
|
|
||||||
|
if (habbo != null) look = FigureUtil.stripBlacklistedClothing(look, habbo.getForbiddenClothing());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.look = look;
|
||||||
|
}
|
||||||
|
|
||||||
public HabboGender getGender()
|
public HabboGender getGender()
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@ import com.eu.habbo.messages.incoming.MessageHandler;
|
|||||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||||
import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer;
|
import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer;
|
||||||
import com.eu.habbo.plugin.events.users.UserSavedLookEvent;
|
import com.eu.habbo.plugin.events.users.UserSavedLookEvent;
|
||||||
|
import com.eu.habbo.util.figure.FigureUtil;
|
||||||
|
|
||||||
public class UserSaveLookEvent extends MessageHandler
|
public class UserSaveLookEvent extends MessageHandler
|
||||||
{
|
{
|
||||||
@ -30,6 +31,12 @@ public class UserSaveLookEvent extends MessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
String look = this.packet.readString();
|
String look = this.packet.readString();
|
||||||
|
|
||||||
|
if (FigureUtil.hasBlacklistedClothing(look, this.client.getHabbo().getForbiddenClothing())) {
|
||||||
|
ScripterManager.scripterDetected(this.client, "The user tried to wear clothing that they have not bought yet.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UserSavedLookEvent lookEvent = new UserSavedLookEvent(this.client.getHabbo(), gender, look);
|
UserSavedLookEvent lookEvent = new UserSavedLookEvent(this.client.getHabbo(), gender, look);
|
||||||
Emulator.getPluginManager().fireEvent(lookEvent);
|
Emulator.getPluginManager().fireEvent(lookEvent);
|
||||||
if(lookEvent.isCancelled())
|
if(lookEvent.isCancelled())
|
||||||
|
@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.users.Habbo;
|
|||||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||||
import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer;
|
import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer;
|
||||||
import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer;
|
import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer;
|
||||||
|
import com.eu.habbo.util.figure.FigureUtil;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@ -57,7 +58,7 @@ public class UpdateUser extends RCONMessage<UpdateUser.JSON>
|
|||||||
|
|
||||||
if (!json.look.isEmpty())
|
if (!json.look.isEmpty())
|
||||||
{
|
{
|
||||||
habbo.getHabboInfo().setLook(json.look);
|
habbo.getHabboInfo().setLook(json.look, json.strip_unredeemed_clothing);
|
||||||
if(habbo.getClient() != null) {
|
if(habbo.getClient() != null) {
|
||||||
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo).compose());
|
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo).compose());
|
||||||
}
|
}
|
||||||
@ -160,6 +161,8 @@ public class UpdateUser extends RCONMessage<UpdateUser.JSON>
|
|||||||
|
|
||||||
|
|
||||||
public String look = "";
|
public String look = "";
|
||||||
|
|
||||||
|
public boolean strip_unredeemed_clothing = false;
|
||||||
//More could be added in the future.
|
//More could be added in the future.
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,65 +0,0 @@
|
|||||||
package com.eu.habbo.util;
|
|
||||||
|
|
||||||
import gnu.trove.map.hash.THashMap;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class FigureUtil
|
|
||||||
{
|
|
||||||
public static THashMap<String, String> getFigureBits(String looks)
|
|
||||||
{
|
|
||||||
THashMap<String, String> bits = new THashMap<>();
|
|
||||||
String[] sets = looks.split("\\.");
|
|
||||||
|
|
||||||
for(String set : sets)
|
|
||||||
{
|
|
||||||
String[] setBits = set.split("-", 2);
|
|
||||||
bits.put(setBits[0], setBits.length > 1 ? setBits[1] : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String mergeFigures(String figure1, String figure2)
|
|
||||||
{
|
|
||||||
return mergeFigures(figure1, figure2, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String mergeFigures(String figure1, String figure2, String[] limitFigure1)
|
|
||||||
{
|
|
||||||
return mergeFigures(figure1, figure2, limitFigure1, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String mergeFigures(String figure1, String figure2, String[] limitFigure1, String[] limitFigure2)
|
|
||||||
{
|
|
||||||
THashMap<String, String> figureBits1 = getFigureBits(figure1);
|
|
||||||
THashMap<String, String> figureBits2 = getFigureBits(figure2);
|
|
||||||
|
|
||||||
StringBuilder finalLook = new StringBuilder();
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> keys : figureBits1.entrySet())
|
|
||||||
{
|
|
||||||
if(limitFigure1 == null || ArrayUtils.contains(limitFigure1, keys.getKey()))
|
|
||||||
{
|
|
||||||
finalLook.append(keys.getKey()).append("-").append(keys.getValue()).append(".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> keys : figureBits2.entrySet())
|
|
||||||
{
|
|
||||||
if(limitFigure2 == null || ArrayUtils.contains(limitFigure2, keys.getKey()))
|
|
||||||
{
|
|
||||||
finalLook.append(keys.getKey()).append("-").append(keys.getValue()).append(".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(finalLook.toString().endsWith("."))
|
|
||||||
{
|
|
||||||
finalLook = new StringBuilder(finalLook.substring(0, finalLook.length() - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return finalLook.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,6 +4,8 @@ import gnu.trove.map.hash.THashMap;
|
|||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
public class FigureUtil
|
public class FigureUtil
|
||||||
{
|
{
|
||||||
@ -32,6 +34,40 @@ public class FigureUtil
|
|||||||
return mergeFigures(figure1, figure2, limitFigure1, null);
|
return mergeFigures(figure1, figure2, limitFigure1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasBlacklistedClothing(String figure, Set<Integer> blacklist) {
|
||||||
|
for (String set : figure.split("\\.")) {
|
||||||
|
String[] pieces = set.split("-");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (pieces.length >= 2 && blacklist.contains(Integer.valueOf(pieces[1]))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String stripBlacklistedClothing(String figure, Set<Integer> blacklist) {
|
||||||
|
StringJoiner joiner = new StringJoiner(".");
|
||||||
|
|
||||||
|
for (String set : figure.split("\\.")) {
|
||||||
|
String[] pieces = set.split("-");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (pieces.length < 2 || !blacklist.contains(Integer.valueOf(pieces[1]))) {
|
||||||
|
joiner.add(set);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
joiner.add(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static String mergeFigures(String figure1, String figure2, String[] limitFigure1, String[] limitFigure2)
|
public static String mergeFigures(String figure1, String figure2, String[] limitFigure1, String[] limitFigure2)
|
||||||
{
|
{
|
||||||
THashMap<String, String> figureBits1 = getFigureBits(figure1);
|
THashMap<String, String> figureBits1 = getFigureBits(figure1);
|
||||||
|
Loading…
Reference in New Issue
Block a user