View difference between Paste ID: QPVZTS08 and 8XPwLZdX
SHOW: | | - or go back to the newest paste.
1
### Eclipse Workspace Patch 1.0
2
#P aCis_gameserver
3
diff --git sql/characters_dressme_data.sql sql/characters_dressme_data.sql
4
new file mode 100644
5
index 0000000..24245a1
6
--- /dev/null
7
+++ sql/characters_dressme_data.sql
8
@@ -0,0 +1,40 @@
9
+/*
10
+Navicat MySQL Data Transfer
11
+
12
+Source Server         : localhost
13
+Source Server Version : 50505
14
+Source Host           : localhost:3306
15
+Source Database       : l2jlotus
16
+
17
+Target Server Type    : MYSQL
18
+Target Server Version : 50505
19
+File Encoding         : 65001
20
+
21
+Date: 2024-03-30 00:33:19
22
+*/
23
+
24
+SET FOREIGN_KEY_CHECKS=0;
25
+
26
+-- ----------------------------
27
+-- Table structure for `characters_dressme_data`
28
+-- ----------------------------
29
+DROP TABLE IF EXISTS `characters_dressme_data`;
30
+CREATE TABLE `characters_dressme_data` (
31
+  `obj_Id` decimal(11,0) NOT NULL DEFAULT 0,
32
+  `armor_skins` varchar(255) DEFAULT NULL,
33
+  `armor_skin_option` int(10) DEFAULT 0,
34
+  `weapon_skins` varchar(255) DEFAULT NULL,
35
+  `weapon_skin_option` int(10) DEFAULT 0,
36
+  `hair_skins` varchar(255) DEFAULT NULL,
37
+  `hair_skin_option` int(10) DEFAULT 0,
38
+  `face_skins` varchar(255) DEFAULT NULL,
39
+  `face_skin_option` int(10) DEFAULT 0,
40
+  PRIMARY KEY (`obj_Id`)
41
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
42
+
43
diff --git data/xml/dressme.xml data/xml/dressme.xml
44
new file mode 100644
45
index 0000000..9482715
46
--- /dev/null
47
+++ data/xml/dressme.xml
48
@@ -0,0 +1,18 @@
49
+<?xml version="1.0" encoding="UTF-8"?>
50
+<list>
51
+	<skin type="armor"> <!-- Armors -->
52
+		<type id="1" name="Draconic Armor" chestId="6379" legsId="0" glovesId="0" feetId="0" priceId="57" priceCount="100"/>
53
+		<type id="2" name="Blue Wolf Leather Armor" chestId="2391" legsId="0" glovesId="0" feetId="0" priceId="57" priceCount="100"/>
54
+	</skin>
55
+	<skin type="weapon"> <!-- Weapons -->
56
+		<type id="1" name="Draconic Bow" weaponId="7575" priceId="57" priceCount="100"/>
57
+		<type id="2" name="Arcana Mace" weaponId="6608"  priceId="57" priceCount="100"/>
58
+		<type id="3" name="Keshanberk*Keshanberk" weaponId="5704" priceId="57" priceCount="100"/>
59
+	</skin>
60
+	<skin type="hair"> <!-- Hairs -->
61
+		<type id="1" name="Cat Ear" hairId="6843" priceId="57" priceCount="100"/>
62
+	</skin>
63
+	<skin type="face"> <!-- Faces -->
64
+		<type id="1" name="Party Mask" faceId="5808" priceId="57" priceCount="100"/>
65
+	</skin>
66
+</list>
67
\ No newline at end of file
68
diff --git config/players.properties config/players.properties
69
index 023dcea..09e43a4 100644
70
--- config/players.properties
71
+++ config/players.properties
72
@@ -239,4 +239,17 @@
73
 
74
 
75
 # Give a Roulette item reward
76
-CustomItemRoulette = 57
77
\ No newline at end of file
78
+CustomItemRoulette = 57
79
+
80
+# DressMe system.
81
+AllowDressMeSystem = True
82
+
83
+# DressMe Command
84
+DressMeCommand = dressme
85
+
86
+# Only for premium account
87
+AllowDressMeForPremiumOnly = False
88
+
89
+
90
+# Players won't see the skins in Olympiad
91
+AllowDressMeInOly = True
92
\ No newline at end of file
93
diff --git Base/Data/XMLDocumentFactory.java Base/Data/XMLDocumentFactory.java
94
new file mode 100644
95
index 0000000..cdf1053
96
--- /dev/null
97
+++ java/Base/Data/XMLDocumentFactory.java
98
+package Base.Data;
99
+
100
+import java.io.File;
101
+
102
+import javax.xml.parsers.DocumentBuilder;
103
+import javax.xml.parsers.DocumentBuilderFactory;
104
+
105
+import org.w3c.dom.Document;
106
+
107
+/**
108
+ * @author Forsaiken
109
+ */
110
+public final class XMLDocumentFactory
111
+{
112
+	public static final XMLDocumentFactory getInstance()
113
+	{
114
+		return SingletonHolder._instance;
115
+	}
116
+	
117
+	private final DocumentBuilder _builder;
118
+	
119
+	protected XMLDocumentFactory() throws Exception
120
+	{
121
+		try
122
+		{
123
+			final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
124
+			factory.setValidating(false);
125
+			factory.setIgnoringComments(true);
126
+			
127
+			_builder = factory.newDocumentBuilder();
128
+		}
129
+		catch (Exception e)
130
+		{
131
+			throw new Exception("Failed initializing", e);
132
+		}
133
+	}
134
+	
135
+	public final Document loadDocument(final String filePath) throws Exception
136
+	{
137
+		return loadDocument(new File(filePath));
138
+	}
139
+	
140
+	public final Document loadDocument(final File file) throws Exception
141
+	{
142
+		if (!file.exists() || !file.isFile())
143
+			throw new Exception("File: " + file.getAbsolutePath() + " doesn't exist and/or is not a file.");
144
+		
145
+		return _builder.parse(file);
146
+	}
147
+	
148
+	public final Document newDocument()
149
+	{
150
+		return _builder.newDocument();
151
+	}
152
+	
153
+	private static class SingletonHolder
154
+	{
155
+		protected static final XMLDocumentFactory _instance;
156
+		
157
+		static
158
+		{
159
+			try
160
+			{
161
+				_instance = new XMLDocumentFactory();
162
+			}
163
+			catch (Exception e)
164
+			{
165
+				throw new ExceptionInInitializerError(e);
166
+			}
167
+		}
168
+	}
169
+}
170
diff --git java/Base/Data/IconTable.java java/Base/Data/IconTable.java
171
new file mode 100644
172
index 0000000..cdf1053
173
--- /dev/null
174
+++ java/Base/Data/IconTable.java
175
+package Base.Data;
176
+
177
+import java.io.File;
178
+import java.util.TreeMap;
179
+import java.util.logging.Level;
180
+import java.util.logging.Logger;
181
+
182
+import org.w3c.dom.Document;
183
+import org.w3c.dom.NamedNodeMap;
184
+import org.w3c.dom.Node;
185
+
186
+public final class IconTable
187
+{
188
+	private final static TreeMap<Integer, String> itemIcons = new TreeMap<>();
189
+	private static Logger _log = Logger.getLogger(IconTable.class.getName());
190
+	
191
+	protected IconTable()
192
+	{
193
+		load();
194
+	}
195
+	
196
+	public void load()
197
+	{
198
+		
199
+		try
200
+		{
201
+			File f = new File("./data/xml/icons.xml");
202
+			Document doc = XMLDocumentFactory.getInstance().loadDocument(f);
203
+			
204
+			Node n = doc.getFirstChild();
205
+			for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
206
+			{
207
+				if (d.getNodeName().equalsIgnoreCase("icon"))
208
+				{
209
+					NamedNodeMap attrs = d.getAttributes();
210
+					
211
+					int id = Integer.valueOf(attrs.getNamedItem("itemId").getNodeValue());
212
+					String value = attrs.getNamedItem("value").getNodeValue();
213
+					itemIcons.put(id, value);
214
+				}
215
+			}
216
+			_log.log(Level.WARNING, "IconTable: loaded " + itemIcons.size() + " icons.");
217
+		}
218
+		catch (Exception e)
219
+		{
220
+			_log.log(Level.WARNING, "IconTable: Error loading from database: " + e.getMessage(), e);
221
+		}
222
+	}
223
+	
224
+	public void reload()
225
+	{
226
+		itemIcons.clear();
227
+		load();
228
+	}
229
+	
230
+	/**
231
+	 * @return the _rewards
232
+	 */
233
+	public TreeMap<Integer, String> getIcon()
234
+	{
235
+		return itemIcons;
236
+	}
237
+	
238
+	public static String getIcon(int id)
239
+	{
240
+		return itemIcons.get(id);
241
+	}
242
+	
243
+	public static IconTable getInstance()
244
+	{
245
+		return SingletonHolder.INSTANCE;
246
+	}
247
+	
248
+	private static class SingletonHolder
249
+	{
250
+		protected static final IconTable INSTANCE = new IconTable();
251
+	}
252
+}
253
254
diff --git java/Base/Skin/DressMeData.java java/Base/Skin/DressMeData.java
255
new file mode 100644
256
index 0000000..cdf1053
257
--- /dev/null
258
+++ java/Base/Skin/DressMeData.java
259
@@ -0,0 +1,216 @@
260
+package Base.Skin;
261
+
262
+import java.util.HashMap;
263
+import java.util.Map;
264
+import java.util.logging.Logger;
265
+
266
+import net.sf.l2j.commons.data.StatSet;
267
+
268
+import org.w3c.dom.Document;
269
+import org.w3c.dom.NamedNodeMap;
270
+import org.w3c.dom.Node;
271
+
272
+import Base.Xml.IXmlReader;
273
+
274
+
275
+
276
+public class DressMeData implements IXmlReader
277
+{
278
+	private static final Logger LOG = Logger.getLogger(DressMeData.class.getName());
279
+	
280
+	private final static Map<Integer, SkinPackage> _armorSkins = new HashMap<>();
281
+	private final static Map<Integer, SkinPackage> _weaponSkins = new HashMap<>();
282
+	private final static Map<Integer, SkinPackage> _hairSkins = new HashMap<>();
283
+	private final static Map<Integer, SkinPackage> _faceSkins = new HashMap<>();
284
+	private final static Map<Integer, SkinPackage> _shieldSkins = new HashMap<>();
285
+	
286
+	public DressMeData()
287
+	{
288
+		load();
289
+	}
290
+	
291
+	public void reload()
292
+	{
293
+		_armorSkins.clear();
294
+		_weaponSkins.clear();
295
+		_hairSkins.clear();
296
+		_faceSkins.clear();
297
+		_shieldSkins.clear();
298
+		
299
+		load();
300
+	}
301
+	
302
+	@Override
303
+	public void load()
304
+	{
305
+		parseDatapackFile("./data/xml/dressme.xml");
306
+		LOG.info(getClass().getSimpleName() + ": Loaded " + _armorSkins.size() + " armor skins");
307
+		LOG.info(getClass().getSimpleName() + ": Loaded " + _weaponSkins.size() + " weapon skins");
308
+		LOG.info(getClass().getSimpleName() + ": Loaded " + _hairSkins.size() + " hair skins");
309
+		LOG.info(getClass().getSimpleName() + ": Loaded " + _faceSkins.size() + " face skins");
310
+		LOG.info(getClass().getSimpleName() + ": Loaded " + _shieldSkins.size() + " shield skins");
311
+	}
312
+	
313
+	@Override
314
+	public void parseDocument(Document doc)
315
+	{
316
+		for (Node list = doc.getFirstChild(); list != null; list = list.getNextSibling())
317
+		{
318
+			if ("list".equalsIgnoreCase(list.getNodeName()))
319
+			{
320
+				for (Node skin = list.getFirstChild(); skin != null; skin = skin.getNextSibling())
321
+				{
322
+					if ("skin".equalsIgnoreCase(skin.getNodeName()))
323
+					{
324
+						final NamedNodeMap attrs = skin.getAttributes();
325
+						
326
+						String type = parseString(attrs, "type");
327
+						
328
+						final StatSet set = new StatSet();
329
+						
330
+						for (Node typeN = skin.getFirstChild(); typeN != null; typeN = typeN.getNextSibling())
331
+						{
332
+							if ("type".equalsIgnoreCase(typeN.getNodeName()))
333
+							{
334
+								final NamedNodeMap attrs2 = typeN.getAttributes();
335
+								
336
+								int id = parseInteger(attrs2, "id");
337
+								String name = parseString(attrs2, "name");
338
+								int weaponId = parseInteger(attrs2, "weaponId", 0);
339
+								int shieldId = parseInteger(attrs2, "shieldId", 0);
340
+								int chestId = parseInteger(attrs2, "chestId", 0);
341
+								int hairId = parseInteger(attrs2, "hairId", 0);
342
+								int faceId = parseInteger(attrs2, "faceId", 0);
343
+								int legsId = parseInteger(attrs2, "legsId", 0);
344
+								int glovesId = parseInteger(attrs2, "glovesId", 0);
345
+								int feetId = parseInteger(attrs2, "feetId", 0);
346
+								int priceId = parseInteger(attrs2, "priceId", 0);
347
+								int priceCount = parseInteger(attrs2, "priceCount", 0);
348
+								
349
+								set.set("type", type);
350
+								
351
+								set.set("id", id);
352
+								set.set("name", name);
353
+								set.set("weaponId", weaponId);
354
+								set.set("shieldId", shieldId);
355
+								set.set("chestId", chestId);
356
+								set.set("hairId", hairId);
357
+								set.set("faceId", faceId);
358
+								set.set("legsId", legsId);
359
+								set.set("glovesId", glovesId);
360
+								set.set("feetId", feetId);
361
+								set.set("priceId", priceId);
362
+								set.set("priceCount", priceCount);
363
+								
364
+								switch (type.toLowerCase())
365
+								{
366
+									case "armor":
367
+										_armorSkins.put(id, new SkinPackage(set));
368
+										break;
369
+									case "weapon":
370
+										_weaponSkins.put(id, new SkinPackage(set));
371
+										break;
372
+									case "hair":
373
+										_hairSkins.put(id, new SkinPackage(set));
374
+										break;
375
+									case "face":
376
+										_faceSkins.put(id, new SkinPackage(set));
377
+										break;
378
+									case "shield":
379
+										_shieldSkins.put(id, new SkinPackage(set));
380
+										break;
381
+								}
382
+							}
383
+						}
384
+					}
385
+				}
386
+			}
387
+		}
388
+		
389
+	}
390
+	
391
+	public SkinPackage getArmorSkinsPackage(int id)
392
+	{
393
+		if (!_armorSkins.containsKey(id))
394
+		{
395
+			return null;
396
+		}
397
+		
398
+		return _armorSkins.get(id);
399
+	}
400
+	
401
+	public Map<Integer, SkinPackage> getArmorSkinOptions()
402
+	{
403
+		return _armorSkins;
404
+	}
405
+	
406
+	public SkinPackage getWeaponSkinsPackage(int id)
407
+	{
408
+		if (!_weaponSkins.containsKey(id))
409
+		{
410
+			return null;
411
+		}
412
+		
413
+		return _weaponSkins.get(id);
414
+	}
415
+	
416
+	public Map<Integer, SkinPackage> getWeaponSkinOptions()
417
+	{
418
+		return _weaponSkins;
419
+	}
420
+	
421
+	public SkinPackage getHairSkinsPackage(int id)
422
+	{
423
+		if (!_hairSkins.containsKey(id))
424
+		{
425
+			return null;
426
+		}
427
+		
428
+		return _hairSkins.get(id);
429
+	}
430
+	
431
+	public Map<Integer, SkinPackage> getHairSkinOptions()
432
+	{
433
+		return _hairSkins;
434
+	}
435
+	
436
+	public SkinPackage getFaceSkinsPackage(int id)
437
+	{
438
+		if (!_faceSkins.containsKey(id))
439
+		{
440
+			return null;
441
+		}
442
+		
443
+		return _faceSkins.get(id);
444
+	}
445
+	
446
+	public Map<Integer, SkinPackage> getFaceSkinOptions()
447
+	{
448
+		return _faceSkins;
449
+	}
450
+	
451
+	public SkinPackage getShieldSkinsPackage(int id)
452
+	{
453
+		if (!_shieldSkins.containsKey(id))
454
+		{
455
+			return null;
456
+		}
457
+		
458
+		return _shieldSkins.get(id);
459
+	}
460
+	
461
+	public Map<Integer, SkinPackage> getShieldSkinOptions()
462
+	{
463
+		return _shieldSkins;
464
+	}
465
+	
466
+	public static DressMeData getInstance()
467
+	{
468
+		return SingletonHolder._instance;
469
+	}
470
+	
471
+	private static class SingletonHolder
472
+	{
473
+		protected static final DressMeData _instance = new DressMeData();
474
+	}
475
+}
476
\ No newline at end of file
477
diff --git java/Base/Skin/SkinPackage.java java/Base/Skin/SkinPackage.java
478
new file mode 100644
479
index 0000000..ff40f74
480
--- /dev/null
481
+++ java/Base/Skin/SkinPackage.java
482
@@ -0,0 +1,104 @@
483
+package Base.Skin;
484
+
485
+import net.sf.l2j.commons.data.StatSet;
486
+
487
+
488
+
489
+public class SkinPackage
490
+{
491
+	private String _type;
492
+	private String _name;
493
+	private int _id;
494
+	private int _weaponId;
495
+	private int _shieldId;
496
+	private int _chestId;
497
+	private int _hairId;
498
+	private int _faceId;
499
+	private int _legsId;
500
+	private int _glovesId;
501
+	private int _feetId;
502
+	private int _priceId;
503
+	private int _priceCount;
504
+	
505
+	public SkinPackage(StatSet set)
506
+	{
507
+		_type = set.getString("type", "default");
508
+		_name = set.getString("name", "NoName");
509
+		_id = set.getInteger("id", 0);
510
+		_weaponId = set.getInteger("weaponId", 0);
511
+		_shieldId = set.getInteger("shieldId", 0);
512
+		_chestId = set.getInteger("chestId", 0);
513
+		_hairId = set.getInteger("hairId", 0);
514
+		_faceId = set.getInteger("faceId", 0);
515
+		_legsId = set.getInteger("legsId", 0);
516
+		_glovesId = set.getInteger("glovesId", 0);
517
+		_feetId = set.getInteger("feetId", 0);
518
+		_priceId = set.getInteger("priceId", 0);
519
+		_priceCount = set.getInteger("priceCount", 0);
520
+	}
521
+	
522
+	public int getId()
523
+	{
524
+		return _id;
525
+	}
526
+	
527
+	public String getType()
528
+	{
529
+		return _type;
530
+	}
531
+	
532
+	public String getName()
533
+	{
534
+		return _name;
535
+	}
536
+	
537
+	public int getWeaponId()
538
+	{
539
+		return _weaponId;
540
+	}
541
+	
542
+	public int getShieldId()
543
+	{
544
+		return _shieldId;
545
+	}
546
+	
547
+	public int getChestId()
548
+	{
549
+		return _chestId;
550
+	}
551
+	
552
+	public int getHairId()
553
+	{
554
+		return _hairId;
555
+	}
556
+	
557
+	public int getFaceId()
558
+	{
559
+		return _faceId;
560
+	}
561
+	
562
+	public int getLegsId()
563
+	{
564
+		return _legsId;
565
+	}
566
+	
567
+	public int getGlovesId()
568
+	{
569
+		return _glovesId;
570
+	}
571
+	
572
+	public int getFeetId()
573
+	{
574
+		return _feetId;
575
+	}
576
+	
577
+	public int getPriceId()
578
+	{
579
+		return _priceId;
580
+	}
581
+	
582
+	public int getPriceCount()
583
+	{
584
+		return _priceCount;
585
+	}
586
+}
587
\ No newline at end of file
588
diff --git java/Base/Xml/IXmlReader.java java/Base/Xml/IXmlReader.java
589
new file mode 100644
590
index 0000000..044830c
591
--- /dev/null
592
+++ java/Base/Xml/IXmlReader.java
593
@@ -0,0 +1,577 @@
594
+
595
+package Base.Xml;
596
+
597
+import java.io.File;
598
+import java.io.FileFilter;
599
+import java.util.logging.Logger;
600
+
601
+import javax.xml.parsers.DocumentBuilder;
602
+import javax.xml.parsers.DocumentBuilderFactory;
603
+
604
+import net.sf.l2j.commons.data.StatSet;
605
+
606
+import net.sf.l2j.gameserver.GameServer;
607
+
608
+
609
+import org.w3c.dom.Document;
610
+import org.w3c.dom.NamedNodeMap;
611
+import org.w3c.dom.Node;
612
+import org.xml.sax.ErrorHandler;
613
+import org.xml.sax.SAXParseException;
614
+
615
+
616
+
617
+public interface IXmlReader
618
+{
619
+	static final Logger LOG = Logger.getLogger(GameServer.class.getName());
620
+	
621
+	static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
622
+	static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
623
+	
624
+	static final XMLFilter XML_FILTER = new XMLFilter();
625
+	
626
+	public void load();
627
+	
628
+	default void parseDatapackFile(String path)
629
+	{
630
+		parseFile(new File(".", path));
631
+	}
632
+	
633
+	default void parseFile(File f)
634
+	{
635
+		if (!getCurrentFileFilter().accept(f))
636
+		{
637
+			LOG.warning("{}: Could not parse {} is not a file or it doesn't exist!");
638
+			return;
639
+		}
640
+		
641
+		final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
642
+		dbf.setNamespaceAware(true);
643
+		dbf.setValidating(false);
644
+		dbf.setIgnoringComments(true);
645
+		
646
+		try
647
+		{
648
+			dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
649
+			final DocumentBuilder db = dbf.newDocumentBuilder();
650
+			db.setErrorHandler(new XMLErrorHandler());
651
+			parseDocument(db.parse(f), f);
652
+		}
653
+		catch (SAXParseException e)
654
+		{
655
+			LOG.warning("{}: Could not parse file {} at line {}, column {}");
656
+			return;
657
+		}
658
+		catch (Exception e)
659
+		{
660
+			LOG.warning("{}: Could not parse file {}");
661
+			return;
662
+		}
663
+	}
664
+	
665
+	default boolean parseDirectory(File file)
666
+	{
667
+		return parseDirectory(file, false);
668
+	}
669
+	
670
+	default boolean parseDirectory(String path)
671
+	{
672
+		return parseDirectory(new File(path), false);
673
+	}
674
+	
675
+	default boolean parseDirectory(String path, boolean recursive)
676
+	{
677
+		return parseDirectory(new File(path), recursive);
678
+	}
679
+	
680
+	default boolean parseDirectory(File dir, boolean recursive)
681
+	{
682
+		if (!dir.exists())
683
+		{
684
+			LOG.warning("{}: Folder {} doesn't exist!");
685
+			return false;
686
+		}
687
+		
688
+		final File[] files = dir.listFiles();
689
+		if (files != null)
690
+		{
691
+			for (File f : files)
692
+			{
693
+				if (recursive && f.isDirectory())
694
+				{
695
+					parseDirectory(f, recursive);
696
+				}
697
+				else if (getCurrentFileFilter().accept(f))
698
+				{
699
+					parseFile(f);
700
+				}
701
+			}
702
+		}
703
+		return true;
704
+	}
705
+	
706
+	default boolean parseDatapackDirectory(String path, boolean recursive)
707
+	{
708
+		return parseDirectory(new File(".", path), recursive);
709
+	}
710
+	
711
+	default void parseDocument(Document doc, File f)
712
+	{
713
+		parseDocument(doc);
714
+	}
715
+	
716
+	default void parseDocument(Document doc)
717
+	{
718
+		LOG.warning("{}: Parser not implemented!");
719
+	}
720
+	
721
+	default Boolean parseBoolean(Node node, Boolean defaultValue)
722
+	{
723
+		return node != null ? Boolean.valueOf(node.getNodeValue()) : defaultValue;
724
+	}
725
+	
726
+	default Boolean parseBoolean(Node node)
727
+	{
728
+		return parseBoolean(node, null);
729
+	}
730
+	
731
+	default Boolean parseBoolean(NamedNodeMap attrs, String name)
732
+	{
733
+		return parseBoolean(attrs.getNamedItem(name));
734
+	}
735
+	
736
+	default Boolean parseBoolean(NamedNodeMap attrs, String name, Boolean defaultValue)
737
+	{
738
+		return parseBoolean(attrs.getNamedItem(name), defaultValue);
739
+	}
740
+	
741
+	default Byte parseByte(Node node, Byte defaultValue)
742
+	{
743
+		return node != null ? Byte.valueOf(node.getNodeValue()) : defaultValue;
744
+	}
745
+	
746
+	default StatSet parseAttributes(Node node)
747
+	{
748
+		final NamedNodeMap attrs = node.getAttributes();
749
+		final StatSet map = new StatSet();
750
+		for (int i = 0; i < attrs.getLength(); i++)
751
+		{
752
+			final Node att = attrs.item(i);
753
+			map.set(att.getNodeName(), att.getNodeValue());
754
+		}
755
+		return map;
756
+	}
757
+	
758
+	/**
759
+	 * Parses a byte value.
760
+	 * @param node the node to parse
761
+	 * @return if the node is not null, the value of the parsed node, otherwise null
762
+	 */
763
+	default Byte parseByte(Node node)
764
+	{
765
+		return parseByte(node, null);
766
+	}
767
+	
768
+	/**
769
+	 * Parses a byte value.
770
+	 * @param attrs the attributes
771
+	 * @param name the name of the attribute to parse
772
+	 * @return if the node is not null, the value of the parsed node, otherwise null
773
+	 */
774
+	default Byte parseByte(NamedNodeMap attrs, String name)
775
+	{
776
+		return parseByte(attrs.getNamedItem(name));
777
+	}
778
+	
779
+	/**
780
+	 * Parses a byte value.
781
+	 * @param attrs the attributes
782
+	 * @param name the name of the attribute to parse
783
+	 * @param defaultValue the default value
784
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
785
+	 */
786
+	default Byte parseByte(NamedNodeMap attrs, String name, Byte defaultValue)
787
+	{
788
+		return parseByte(attrs.getNamedItem(name), defaultValue);
789
+	}
790
+	
791
+	/**
792
+	 * Parses a short value.
793
+	 * @param node the node to parse
794
+	 * @param defaultValue the default value
795
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
796
+	 */
797
+	default Short parseShort(Node node, Short defaultValue)
798
+	{
799
+		return node != null ? Short.valueOf(node.getNodeValue()) : defaultValue;
800
+	}
801
+	
802
+	/**
803
+	 * Parses a short value.
804
+	 * @param node the node to parse
805
+	 * @return if the node is not null, the value of the parsed node, otherwise null
806
+	 */
807
+	default Short parseShort(Node node)
808
+	{
809
+		return parseShort(node, null);
810
+	}
811
+	
812
+	/**
813
+	 * Parses a short value.
814
+	 * @param attrs the attributes
815
+	 * @param name the name of the attribute to parse
816
+	 * @return if the node is not null, the value of the parsed node, otherwise null
817
+	 */
818
+	default Short parseShort(NamedNodeMap attrs, String name)
819
+	{
820
+		return parseShort(attrs.getNamedItem(name));
821
+	}
822
+	
823
+	/**
824
+	 * Parses a short value.
825
+	 * @param attrs the attributes
826
+	 * @param name the name of the attribute to parse
827
+	 * @param defaultValue the default value
828
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
829
+	 */
830
+	default Short parseShort(NamedNodeMap attrs, String name, Short defaultValue)
831
+	{
832
+		return parseShort(attrs.getNamedItem(name), defaultValue);
833
+	}
834
+	
835
+	/**
836
+	 * Parses an int value.
837
+	 * @param node the node to parse
838
+	 * @param defaultValue the default value
839
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
840
+	 */
841
+	default int parseInt(Node node, Integer defaultValue)
842
+	{
843
+		return node != null ? Integer.parseInt(node.getNodeValue()) : defaultValue;
844
+	}
845
+	
846
+	/**
847
+	 * Parses an int value.
848
+	 * @param node the node to parse
849
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
850
+	 */
851
+	default int parseInt(Node node)
852
+	{
853
+		return parseInt(node, -1);
854
+	}
855
+	
856
+	/**
857
+	 * Parses an integer value.
858
+	 * @param node the node to parse
859
+	 * @param defaultValue the default value
860
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
861
+	 */
862
+	default Integer parseInteger(Node node, Integer defaultValue)
863
+	{
864
+		return node != null ? Integer.valueOf(node.getNodeValue()) : defaultValue;
865
+	}
866
+	
867
+	/**
868
+	 * Parses an integer value.
869
+	 * @param node the node to parse
870
+	 * @return if the node is not null, the value of the parsed node, otherwise null
871
+	 */
872
+	default Integer parseInteger(Node node)
873
+	{
874
+		return parseInteger(node, null);
875
+	}
876
+	
877
+	/**
878
+	 * Parses an integer value.
879
+	 * @param attrs the attributes
880
+	 * @param name the name of the attribute to parse
881
+	 * @return if the node is not null, the value of the parsed node, otherwise null
882
+	 */
883
+	default Integer parseInteger(NamedNodeMap attrs, String name)
884
+	{
885
+		return parseInteger(attrs.getNamedItem(name));
886
+	}
887
+	
888
+	/**
889
+	 * Parses an integer value.
890
+	 * @param attrs the attributes
891
+	 * @param name the name of the attribute to parse
892
+	 * @param defaultValue the default value
893
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
894
+	 */
895
+	default Integer parseInteger(NamedNodeMap attrs, String name, Integer defaultValue)
896
+	{
897
+		return parseInteger(attrs.getNamedItem(name), defaultValue);
898
+	}
899
+	
900
+	/**
901
+	 * Parses a long value.
902
+	 * @param node the node to parse
903
+	 * @param defaultValue the default value
904
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
905
+	 */
906
+	default Long parseLong(Node node, Long defaultValue)
907
+	{
908
+		return node != null ? Long.valueOf(node.getNodeValue()) : defaultValue;
909
+	}
910
+	
911
+	/**
912
+	 * Parses a long value.
913
+	 * @param node the node to parse
914
+	 * @return if the node is not null, the value of the parsed node, otherwise null
915
+	 */
916
+	default Long parseLong(Node node)
917
+	{
918
+		return parseLong(node, null);
919
+	}
920
+	
921
+	/**
922
+	 * Parses a long value.
923
+	 * @param attrs the attributes
924
+	 * @param name the name of the attribute to parse
925
+	 * @return if the node is not null, the value of the parsed node, otherwise null
926
+	 */
927
+	default Long parseLong(NamedNodeMap attrs, String name)
928
+	{
929
+		return parseLong(attrs.getNamedItem(name));
930
+	}
931
+	
932
+	/**
933
+	 * Parses a long value.
934
+	 * @param attrs the attributes
935
+	 * @param name the name of the attribute to parse
936
+	 * @param defaultValue the default value
937
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
938
+	 */
939
+	default Long parseLong(NamedNodeMap attrs, String name, Long defaultValue)
940
+	{
941
+		return parseLong(attrs.getNamedItem(name), defaultValue);
942
+	}
943
+	
944
+	/**
945
+	 * Parses a float value.
946
+	 * @param node the node to parse
947
+	 * @param defaultValue the default value
948
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
949
+	 */
950
+	default Float parseFloat(Node node, Float defaultValue)
951
+	{
952
+		return node != null ? Float.valueOf(node.getNodeValue()) : defaultValue;
953
+	}
954
+	
955
+	/**
956
+	 * Parses a float value.
957
+	 * @param node the node to parse
958
+	 * @return if the node is not null, the value of the parsed node, otherwise null
959
+	 */
960
+	default Float parseFloat(Node node)
961
+	{
962
+		return parseFloat(node, null);
963
+	}
964
+	
965
+	/**
966
+	 * Parses a float value.
967
+	 * @param attrs the attributes
968
+	 * @param name the name of the attribute to parse
969
+	 * @return if the node is not null, the value of the parsed node, otherwise null
970
+	 */
971
+	default Float parseFloat(NamedNodeMap attrs, String name)
972
+	{
973
+		return parseFloat(attrs.getNamedItem(name));
974
+	}
975
+	
976
+	/**
977
+	 * Parses a float value.
978
+	 * @param attrs the attributes
979
+	 * @param name the name of the attribute to parse
980
+	 * @param defaultValue the default value
981
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
982
+	 */
983
+	default Float parseFloat(NamedNodeMap attrs, String name, Float defaultValue)
984
+	{
985
+		return parseFloat(attrs.getNamedItem(name), defaultValue);
986
+	}
987
+	
988
+	/**
989
+	 * Parses a double value.
990
+	 * @param node the node to parse
991
+	 * @param defaultValue the default value
992
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
993
+	 */
994
+	default Double parseDouble(Node node, Double defaultValue)
995
+	{
996
+		return node != null ? Double.valueOf(node.getNodeValue()) : defaultValue;
997
+	}
998
+	
999
+	/**
1000
+	 * Parses a double value.
1001
+	 * @param node the node to parse
1002
+	 * @return if the node is not null, the value of the parsed node, otherwise null
1003
+	 */
1004
+	default Double parseDouble(Node node)
1005
+	{
1006
+		return parseDouble(node, null);
1007
+	}
1008
+	
1009
+	/**
1010
+	 * Parses a double value.
1011
+	 * @param attrs the attributes
1012
+	 * @param name the name of the attribute to parse
1013
+	 * @return if the node is not null, the value of the parsed node, otherwise null
1014
+	 */
1015
+	default Double parseDouble(NamedNodeMap attrs, String name)
1016
+	{
1017
+		return parseDouble(attrs.getNamedItem(name));
1018
+	}
1019
+	
1020
+	/**
1021
+	 * Parses a double value.
1022
+	 * @param attrs the attributes
1023
+	 * @param name the name of the attribute to parse
1024
+	 * @param defaultValue the default value
1025
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
1026
+	 */
1027
+	default Double parseDouble(NamedNodeMap attrs, String name, Double defaultValue)
1028
+	{
1029
+		return parseDouble(attrs.getNamedItem(name), defaultValue);
1030
+	}
1031
+	
1032
+	/**
1033
+	 * Parses a string value.
1034
+	 * @param node the node to parse
1035
+	 * @param defaultValue the default value
1036
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
1037
+	 */
1038
+	default String parseString(Node node, String defaultValue)
1039
+	{
1040
+		return node != null ? node.getNodeValue() : defaultValue;
1041
+	}
1042
+	
1043
+	/**
1044
+	 * Parses a string value.
1045
+	 * @param node the node to parse
1046
+	 * @return if the node is not null, the value of the parsed node, otherwise null
1047
+	 */
1048
+	default String parseString(Node node)
1049
+	{
1050
+		return parseString(node, null);
1051
+	}
1052
+	
1053
+	/**
1054
+	 * Parses a string value.
1055
+	 * @param attrs the attributes
1056
+	 * @param name the name of the attribute to parse
1057
+	 * @return if the node is not null, the value of the parsed node, otherwise null
1058
+	 */
1059
+	default String parseString(NamedNodeMap attrs, String name)
1060
+	{
1061
+		return parseString(attrs.getNamedItem(name));
1062
+	}
1063
+	
1064
+	/**
1065
+	 * Parses a string value.
1066
+	 * @param attrs the attributes
1067
+	 * @param name the name of the attribute to parse
1068
+	 * @param defaultValue the default value
1069
+	 * @return if the node is not null, the value of the parsed node, otherwise the default value
1070
+	 */
1071
+	default String parseString(NamedNodeMap attrs, String name, String defaultValue)
1072
+	{
1073
+		return parseString(attrs.getNamedItem(name), defaultValue);
1074
+	}
1075
+	
1076
+	/**
1077
+	 * Parses an enumerated value.
1078
+	 * @param <T> the enumerated type
1079
+	 * @param node the node to parse
1080
+	 * @param clazz the class of the enumerated
1081
+	 * @param defaultValue the default value
1082
+	 * @return if the node is not null and the node value is valid the parsed value, otherwise the default value
1083
+	 */
1084
+	default <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz, T defaultValue)
1085
+	{
1086
+		if (node == null)
1087
+		{
1088
+			return defaultValue;
1089
+		}
1090
+		
1091
+		try
1092
+		{
1093
+			return Enum.valueOf(clazz, node.getNodeValue());
1094
+		}
1095
+		catch (IllegalArgumentException e)
1096
+		{
1097
+			LOG.warning("Invalid value specified for node: {} specified value: {} should be enum value of \"{}\" using default value: {}");
1098
+			return defaultValue;
1099
+		}
1100
+	}
1101
+	
1102
+	/**
1103
+	 * Parses an enumerated value.
1104
+	 * @param <T> the enumerated type
1105
+	 * @param node the node to parse
1106
+	 * @param clazz the class of the enumerated
1107
+	 * @return if the node is not null and the node value is valid the parsed value, otherwise null
1108
+	 */
1109
+	default <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz)
1110
+	{
1111
+		return parseEnum(node, clazz, null);
1112
+	}
1113
+	
1114
+	/**
1115
+	 * Parses an enumerated value.
1116
+	 * @param <T> the enumerated type
1117
+	 * @param attrs the attributes
1118
+	 * @param clazz the class of the enumerated
1119
+	 * @param name the name of the attribute to parse
1120
+	 * @return if the node is not null and the node value is valid the parsed value, otherwise null
1121
+	 */
1122
+	default <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name)
1123
+	{
1124
+		return parseEnum(attrs.getNamedItem(name), clazz);
1125
+	}
1126
+	
1127
+	/**
1128
+	 * Parses an enumerated value.
1129
+	 * @param <T> the enumerated type
1130
+	 * @param attrs the attributes
1131
+	 * @param clazz the class of the enumerated
1132
+	 * @param name the name of the attribute to parse
1133
+	 * @param defaultValue the default value
1134
+	 * @return if the node is not null and the node value is valid the parsed value, otherwise the default value
1135
+	 */
1136
+	default <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name, T defaultValue)
1137
+	{
1138
+		return parseEnum(attrs.getNamedItem(name), clazz, defaultValue);
1139
+	}
1140
+	
1141
+	/**
1142
+	 * Gets the current file filter.
1143
+	 * @return the current file filter
1144
+	 */
1145
+	default FileFilter getCurrentFileFilter()
1146
+	{
1147
+		return XML_FILTER;
1148
+	}
1149
+	
1150
+	static class XMLErrorHandler implements ErrorHandler
1151
+	{
1152
+		@Override
1153
+		public void warning(SAXParseException e) throws SAXParseException
1154
+		{
1155
+			throw e;
1156
+		}
1157
+		
1158
+		@Override
1159
+		public void error(SAXParseException e) throws SAXParseException
1160
+		{
1161
+			throw e;
1162
+		}
1163
+		
1164
+		@Override
1165
+		public void fatalError(SAXParseException e) throws SAXParseException
1166
+		{
1167
+			throw e;
1168
+		}
1169
+	}
1170
+}
1171
diff --git java/Base/Xml/XMLFilter.java java/Base/Xml/XMLFilter.java
1172
new file mode 100644
1173
index 0000000..faa1805
1174
--- /dev/null
1175
+++ java/Base/Xml/XMLFilter.java
1176
@@ -0,0 +1,17 @@
1177
+package Base.Xml;
1178
+
1179
+import java.io.File;
1180
+import java.io.FileFilter;
1181
+
1182
+public class XMLFilter implements FileFilter
1183
+{
1184
+	@Override
1185
+	public boolean accept(File f)
1186
+	{
1187
+		if ((f == null) || !f.isFile())
1188
+		{
1189
+			return false;
1190
+		}
1191
+		return f.getName().toLowerCase().endsWith(".xml");
1192
+	}
1193
+}
1194
diff --git java/net/sf/l2j/Config.java java/net/sf/l2j/Config.java
1195
index 740f51c..7a589d1 100644
1196
--- java/net/sf/l2j/Config.java
1197
+++ java/net/sf/l2j/Config.java
1198
@@ -56,6 +56,11 @@
1199
 	public static final String SIEGE_FILE = "./config/siege.properties";
1200
 	public static final String HWID_FILE = "./config/hwid.properties";
1201
 	
1202
+	public static boolean ALLOW_DRESS_ME_SYSTEM;
1203
+	public static String DRESS_ME_COMMAND;
1204
+	public static boolean ALLOW_DRESS_ME_FOR_PREMIUM;
1205
+	public static boolean ALLOW_DRESS_ME_IN_OLY;
1206
+	
1207
 	public static int CUSTOM_ITEM_ROULETTE;
1208
 	
1209
 	/** Annunce Pvp And Pk Kills */
1210
@@ -1970,6 +1975,11 @@
1211
 		
1212
 		CUSTOM_ITEM_ROULETTE = players.getProperty("CustomItemRoulette", 0);
1213
 		
1214
+		ALLOW_DRESS_ME_SYSTEM = players.getProperty("AllowDressMeSystem", false);
1215
+		DRESS_ME_COMMAND = players.getProperty("DressMeCommand", "dressme");
1216
+		ALLOW_DRESS_ME_FOR_PREMIUM = players.getProperty("AllowDressMeForPremiumOnly", false);
1217
+		ALLOW_DRESS_ME_IN_OLY = players.getProperty("AllowDressMeInOly", false);
1218
+		
1219
 		EFFECT_CANCELING = players.getProperty("CancelLesserEffect", true);
1220
 		HP_REGEN_MULTIPLIER = players.getProperty("HpRegenMultiplier", 1.);
1221
 		MP_REGEN_MULTIPLIER = players.getProperty("MpRegenMultiplier", 1.);
1222
diff --git java/net/sf/l2j/gameserver/GameServer.java java/net/sf/l2j/gameserver/GameServer.java
1223
index 1600d9a..d1211b7 100644
1224
--- java/net/sf/l2j/gameserver/GameServer.java
1225
+++ java/net/sf/l2j/gameserver/GameServer.java
1226
@@ -118,6 +118,7 @@
1227
+import Base.Data.IconTable;
1228
+import Base.Data.XMLDocumentFactory;
1229
 import Base.Roullete.RouletteData;
1230
+import Base.Skin.DressMeData;
1231
 import hwid.hwid;
1232
 
1233
 public class GameServer
1234
@@ -314,6 +315,12 @@
1235
 		RouletteData.getInstance();
1236
+       XMLDocumentFactory.getInstace();
1237
+ 		IconTable.getInstance();		
1238
+		if (Config.ALLOW_DRESS_ME_SYSTEM)
1239
+		{
1240
+			StringUtil.printSection("Dress Me / Skins");
1241
+			DressMeData.getInstance();
1242
+		}
1243
+		
1244
 		StringUtil.printSection("Handlers");
1245
 		LOGGER.info("Loaded {} admin command handlers.", AdminCommandHandler.getInstance().size());
1246
 		LOGGER.info("Loaded {} chat handlers.", ChatHandler.getInstance().size());
1247
diff --git java/net/sf/l2j/gameserver/data/xml/ItemData.java java/net/sf/l2j/gameserver/data/xml/ItemData.java
1248
index fb35d7c..abb8736 100644
1249
--- java/net/sf/l2j/gameserver/data/xml/ItemData.java
1250
+++ java/net/sf/l2j/gameserver/data/xml/ItemData.java
1251
@@ -3,10 +3,13 @@
1252
 import java.io.File;
1253
 import java.util.HashMap;
1254
 import java.util.Map;
1255
+import java.util.logging.Level;
1256
 
1257
 import net.sf.l2j.commons.logging.CLogger;
1258
 
1259
+
1260
 import net.sf.l2j.gameserver.data.DocumentItem;
1261
+import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
1262
 import net.sf.l2j.gameserver.model.item.kind.Armor;
1263
 import net.sf.l2j.gameserver.model.item.kind.EtcItem;
1264
 import net.sf.l2j.gameserver.model.item.kind.Item;
1265
@@ -101,6 +104,47 @@
1266
 		return SingletonHolder.INSTANCE;
1267
 	}
1268
 	
1269
+	
1270
+	
1271
+	
1272
+	
1273
+	public ItemInstance createDummyItem(final int itemId)
1274
+	{
1275
+		final Item item = getTemplate(itemId);
1276
+		
1277
+		if (item == null)
1278
+		{
1279
+			return null;
1280
+		}
1281
+		
1282
+		ItemInstance temp = new ItemInstance(0, item);
1283
+		
1284
+		try
1285
+		{
1286
+			temp = new ItemInstance(0, itemId);
1287
+		}
1288
+		catch (final ArrayIndexOutOfBoundsException e)
1289
+		{
1290
+	
1291
+				e.printStackTrace();
1292
+			
1293
+		}
1294
+		
1295
+		if (temp.getItem() == null)
1296
+		{
1297
+			LOGGER.warn(Level.WARNING, "ItemTable: Item Template missing for Id: {}" + " " + itemId);
1298
+		}
1299
+		
1300
+		return temp;
1301
+	}	
1302
+	
1303
+	
1304
+	
1305
+	
1306
+	
1307
+	
1308
+	
1309
+	
1310
 	private static class SingletonHolder
1311
 	{
1312
 		protected static final ItemData INSTANCE = new ItemData();
1313
diff --git java/net/sf/l2j/gameserver/handler/BypassHandler.java java/net/sf/l2j/gameserver/handler/BypassHandler.java
1314
new file mode 100644
1315
index 0000000..ad2fbd4
1316
--- /dev/null
1317
+++ java/net/sf/l2j/gameserver/handler/BypassHandler.java
1318
@@ -0,0 +1,69 @@
1319
+package net.sf.l2j.gameserver.handler;
1320
+
1321
+import java.util.HashMap;
1322
+import java.util.Map;
1323
+import java.util.logging.Logger;
1324
+
1325
+import net.sf.l2j.Config;
1326
+
1327
+
1328
+
1329
+/**
1330
+ * @author Dwight
1331
+ */
1332
+public class BypassHandler
1333
+{
1334
+	private static Logger _log = Logger.getLogger(BypassHandler.class.getName());
1335
+	private final Map<Integer, IBypassHandler> _datatable = new HashMap<>();
1336
+	
1337
+	public static BypassHandler getInstance()
1338
+	{
1339
+		return SingletonHolder._instance;
1340
+	}
1341
+	
1342
+	private BypassHandler()
1343
+	{
1344
+		
1345
+	
1346
+		
1347
+	}
1348
+	
1349
+	public void registerBypassHandler(IBypassHandler handler)
1350
+	{
1351
+		String[] ids = handler.getBypassHandlersList();
1352
+		for (int i = 0; i < ids.length; i++)
1353
+		{
1354
+			if (Config.PACKET_HANDLER_DEBUG)
1355
+			{
1356
+				_log.fine("Adding handler for command " + ids[i]);
1357
+			}
1358
+			_datatable.put(ids[i].hashCode(), handler);
1359
+		}
1360
+	}
1361
+	
1362
+	public IBypassHandler getBypassHandler(String bypass)
1363
+	{
1364
+		String command = bypass;
1365
+		
1366
+		if (bypass.indexOf(" ") != -1)
1367
+		{
1368
+			command = bypass.substring(0, bypass.indexOf(" "));
1369
+		}
1370
+		
1371
+		if (Config.PACKET_HANDLER_DEBUG)
1372
+		{
1373
+			_log.fine("getting handler for command: " + command + " -> " + (_datatable.get(command.hashCode()) != null));
1374
+		}
1375
+		return _datatable.get(command.hashCode());
1376
+	}
1377
+	
1378
+	public int size()
1379
+	{
1380
+		return _datatable.size();
1381
+	}
1382
+	
1383
+	private static class SingletonHolder
1384
+	{
1385
+		protected static final BypassHandler _instance = new BypassHandler();
1386
+	}
1387
+}
1388
diff --git java/net/sf/l2j/gameserver/handler/CustomBypassHandler.java java/net/sf/l2j/gameserver/handler/CustomBypassHandler.java
1389
new file mode 100644
1390
index 0000000..e07fdff
1391
--- /dev/null
1392
+++ java/net/sf/l2j/gameserver/handler/CustomBypassHandler.java
1393
@@ -0,0 +1,70 @@
1394
+
1395
+package net.sf.l2j.gameserver.handler;
1396
+
1397
+import java.util.HashMap;
1398
+import java.util.Map;
1399
+
1400
+import net.sf.l2j.gameserver.handler.voicedcommandhandlers.DressMe;
1401
+import net.sf.l2j.gameserver.model.actor.Player;
1402
+
1403
+
1404
+
1405
+
1406
+public class CustomBypassHandler
1407
+{
1408
+
1409
+	
1410
+	private static CustomBypassHandler _instance = null;
1411
+	private final Map<String, ICustomByPassHandler> _handlers;
1412
+	
1413
+	private CustomBypassHandler()
1414
+	{
1415
+		_handlers = new HashMap<>();
1416
+		
1417
+		
1418
+		registerCustomBypassHandler(new DressMe());
1419
+	}
1420
+	
1421
+	public static CustomBypassHandler getInstance()
1422
+	{
1423
+		if (_instance == null)
1424
+		{
1425
+			_instance = new CustomBypassHandler();
1426
+		}
1427
+		
1428
+		return _instance;
1429
+	}
1430
+	
1431
+	public void registerCustomBypassHandler(final ICustomByPassHandler handler)
1432
+	{
1433
+		for (final String s : handler.getByPassCommands())
1434
+		{
1435
+			_handlers.put(s, handler);
1436
+		}
1437
+	}
1438
+	
1439
+	public void handleBypass(final Player player, final String command)
1440
+	{
1441
+		String cmd = "";
1442
+		String params = "";
1443
+		final int iPos = command.indexOf(" ");
1444
+		if (iPos != -1)
1445
+		{
1446
+			cmd = command.substring(7, iPos);
1447
+			params = command.substring(iPos + 1);
1448
+		}
1449
+		else
1450
+		{
1451
+			cmd = command.substring(7);
1452
+		}
1453
+		final ICustomByPassHandler ch = _handlers.get(cmd);
1454
+		if (ch != null)
1455
+		{
1456
+			ch.handleCommand(cmd, player, params);
1457
+		}
1458
+		else
1459
+		{
1460
+
1461
+		}
1462
+	}
1463
+}
1464
\ No newline at end of file
1465
diff --git java/net/sf/l2j/gameserver/handler/IBypassHandler.java java/net/sf/l2j/gameserver/handler/IBypassHandler.java
1466
new file mode 100644
1467
index 0000000..a942b63
1468
--- /dev/null
1469
+++ java/net/sf/l2j/gameserver/handler/IBypassHandler.java
1470
@@ -0,0 +1,13 @@
1471
+package net.sf.l2j.gameserver.handler;
1472
+
1473
+import net.sf.l2j.gameserver.model.actor.Player;
1474
+
1475
+/**
1476
+ * @author Dwight
1477
+ */
1478
+public interface IBypassHandler
1479
+{
1480
+	public boolean handleBypass(String bypass, Player activeChar);
1481
+	
1482
+	public String[] getBypassHandlersList();
1483
+}
1484
diff --git java/net/sf/l2j/gameserver/handler/ICustomByPassHandler.java java/net/sf/l2j/gameserver/handler/ICustomByPassHandler.java
1485
new file mode 100644
1486
index 0000000..6b4c1b4
1487
--- /dev/null
1488
+++ java/net/sf/l2j/gameserver/handler/ICustomByPassHandler.java
1489
@@ -0,0 +1,10 @@
1490
+package net.sf.l2j.gameserver.handler;
1491
+
1492
+import net.sf.l2j.gameserver.model.actor.Player;
1493
+
1494
+public interface ICustomByPassHandler
1495
+{
1496
+	public String[] getByPassCommands();
1497
+	
1498
+	public void handleCommand(String command, Player player, String parameters);
1499
+}
1500
diff --git java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/DressMe.java java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/DressMe.java
1501
new file mode 100644
1502
index 0000000..1946b57
1503
--- /dev/null
1504
+++ java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/DressMe.java
1505
@@ -0,0 +1,106 @@
1506
+package net.sf.l2j.gameserver.handler.voicedcommandhandlers;
1507
+
1508
+import java.text.SimpleDateFormat;
1509
+import java.util.Date;
1510
+
1511
+import net.sf.l2j.Config;
1512
+import net.sf.l2j.gameserver.data.HTMLData;
1513
+import net.sf.l2j.gameserver.handler.ICustomByPassHandler;
1514
+import net.sf.l2j.gameserver.handler.IVoicedCommandHandler;
1515
+import net.sf.l2j.gameserver.model.actor.Player;
1516
+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
1517
+import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
1518
+import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
1519
+
1520
+public class DressMe implements IVoicedCommandHandler, ICustomByPassHandler
1521
+{
1522
+	private static String[] _voicedCommands =
1523
+	{
1524
+		Config.DRESS_ME_COMMAND
1525
+	};
1526
+	
1527
+	@Override
1528
+	public boolean useVoicedCommand(String command, Player activeChar, String target)
1529
+	{
1530
+		
1531
+		if (Config.ALLOW_DRESS_ME_FOR_PREMIUM && activeChar.getPremiumService() == 0)
1532
+		{
1533
+			activeChar.sendMessage("You're not The Premium account.");
1534
+			activeChar.sendPacket(new ExShowScreenMessage("You're not The Premium account.", 1000));
1535
+			activeChar.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
1536
+			return false;
1537
+		}
1538
+		
1539
+		if (!Config.ALLOW_DRESS_ME_SYSTEM)
1540
+		{
1541
+			
1542
+			activeChar.sendMessage("El Sistema de Skin Esta Desactivado.");
1543
+			return false;
1544
+		}
1545
+		
1546
+		if (command.startsWith(Config.DRESS_ME_COMMAND))
1547
+		{
1548
+			showHtm(activeChar);
1549
+		}
1550
+		
1551
+		return true;
1552
+	}
1553
+	
1554
+	private static void showHtm(Player player)
1555
+	{
1556
+		NpcHtmlMessage htm = new NpcHtmlMessage(1);
1557
+		String text = HTMLData.getInstance().getHtm(player.getLocale(), "html/dressme/index.htm");
1558
+		
1559
+		htm.setHtml(text);
1560
+		
1561
+		{
1562
+			htm.replace("%time%", sdf.format(new Date(System.currentTimeMillis())));
1563
+			htm.replace("%dat%", (new SimpleDateFormat("dd/MM/yyyy")).format(new Date(System.currentTimeMillis())));
1564
+			
1565
+		}
1566
+		
1567
+		player.sendPacket(htm);
1568
+	}
1569
+	
1570
+	static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
1571
+	
1572
+	@Override
1573
+	public String[] getVoicedCommandList()
1574
+	{
1575
+		return _voicedCommands;
1576
+	}
1577
+	
1578
+	@Override
1579
+	public String[] getByPassCommands()
1580
+	{
1581
+		return new String[]
1582
+		{
1583
+			"dressme_back"
1584
+		};
1585
+	}
1586
+	
1587
+	private enum CommandEnum
1588
+	{
1589
+		dressme_back,
1590
+	}
1591
+	
1592
+	@Override
1593
+	public void handleCommand(String command, Player player, String parameters)
1594
+	{
1595
+		CommandEnum comm = CommandEnum.valueOf(command);
1596
+		
1597
+		if (comm == null)
1598
+		{
1599
+			return;
1600
+		}
1601
+		
1602
+		switch (comm)
1603
+		{
1604
+			case dressme_back:
1605
+			{
1606
+				showHtm(player);
1607
+			}
1608
+				break;
1609
+		}
1610
+	}
1611
+}
1612
\ No newline at end of file
1613
diff --git java/net/sf/l2j/gameserver/model/CharSelectSlot.java java/net/sf/l2j/gameserver/model/CharSelectSlot.java
1614
index 5e84997..0e316bf 100644
1615
--- java/net/sf/l2j/gameserver/model/CharSelectSlot.java
1616
+++ java/net/sf/l2j/gameserver/model/CharSelectSlot.java
1617
@@ -49,6 +49,11 @@
1618
 	private int _z = 0;
1619
 	private int _accessLevel = 0;
1620
 	
1621
+	private int _armorSkinOption = 0;
1622
+	private int _weaponSkinOption = 0;
1623
+	private int _hairSkinOption = 0;
1624
+	private int _faceSkinOption = 0;
1625
+	
1626
 	public CharSelectSlot(int objectId, String name)
1627
 	{
1628
 		_objectId = objectId;
1629
@@ -368,4 +373,45 @@
1630
 		}
1631
 		return paperdoll;
1632
 	}
1633
+	
1634
+	public void setArmorSkinOption(int armorSkinOption)
1635
+	{
1636
+		_armorSkinOption = armorSkinOption;
1637
+	}
1638
+	
1639
+	public int getArmorSkinOption()
1640
+	{
1641
+		return _armorSkinOption;
1642
+	}
1643
+	
1644
+	public void setWeaponSkinOption(int armorSkinOption)
1645
+	{
1646
+		_weaponSkinOption = armorSkinOption;
1647
+	}
1648
+	
1649
+	public int getWeaponSkinOption()
1650
+	{
1651
+		return _weaponSkinOption;
1652
+	}
1653
+	
1654
+	public void setHairSkinOption(int hairSkinOption)
1655
+	{
1656
+		_hairSkinOption = hairSkinOption;
1657
+	}
1658
+	
1659
+	public int getHairSkinOption()
1660
+	{
1661
+		return _hairSkinOption;
1662
+	}
1663
+	
1664
+	public void setFaceSkinOption(int faceSkinOption)
1665
+	{
1666
+		_faceSkinOption = faceSkinOption;
1667
+	}
1668
+	
1669
+	public int getFaceSkinOption()
1670
+	{
1671
+		return _faceSkinOption;
1672
+	}
1673
+	
1674
 }
1675
\ No newline at end of file
1676
diff --git java/net/sf/l2j/gameserver/model/actor/Player.java java/net/sf/l2j/gameserver/model/actor/Player.java
1677
index 670a9d4..9769f20 100644
1678
--- java/net/sf/l2j/gameserver/model/actor/Player.java
1679
+++ java/net/sf/l2j/gameserver/model/actor/Player.java
1680
@@ -15,6 +15,7 @@
1681
 import java.util.Set;
1682
 import java.util.concurrent.ConcurrentHashMap;
1683
 import java.util.concurrent.ConcurrentSkipListMap;
1684
+import java.util.concurrent.CopyOnWriteArrayList;
1685
 import java.util.concurrent.Future;
1686
 import java.util.concurrent.ScheduledFuture;
1687
 import java.util.concurrent.atomic.AtomicInteger;
1688
@@ -185,6 +186,7 @@
1689
 import net.sf.l2j.gameserver.network.serverpackets.ExPCCafePointInfo;
1690
 import net.sf.l2j.gameserver.network.serverpackets.ExServerPrimitive;
1691
 import net.sf.l2j.gameserver.network.serverpackets.ExSetCompassZoneCode;
1692
+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
1693
 import net.sf.l2j.gameserver.network.serverpackets.ExStorageMaxCount;
1694
 import net.sf.l2j.gameserver.network.serverpackets.HennaInfo;
1695
 import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
1696
@@ -196,6 +198,7 @@
1697
 import net.sf.l2j.gameserver.network.serverpackets.ObserverEnd;
1698
 import net.sf.l2j.gameserver.network.serverpackets.ObserverStart;
1699
 import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowUpdate;
1700
+import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
1701
 import net.sf.l2j.gameserver.network.serverpackets.PledgeShowMemberListDelete;
1702
 import net.sf.l2j.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
1703
 import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreListBuy;
1704
@@ -246,12 +249,32 @@
1705
 import net.sf.l2j.gameserver.taskmanager.ShadowItemTaskManager;
1706
 import net.sf.l2j.gameserver.taskmanager.WaterTaskManager;
1707
 
1708
+import Base.Skin.DressMeData;
1709
+
1710
 /**
1711
  * This class represents a player in the world.<br>
1712
  * There is always a client-thread connected to this (except if a player-store is activated upon logout).
1713
  */
1714
 public final class Player extends Playable
1715
 {
1716
+	
1717
+	private int _armorSkinOption = 0;
1718
+	private int _weaponSkinOption = 0;
1719
+	private int _hairSkinOption = 0;
1720
+	private int _faceSkinOption = 0;
1721
+	private int _shieldSkinOption = 0;
1722
+	
1723
+	private boolean isTryingSkin = false;
1724
+	private boolean isTryingSkinPremium = false;
1725
+	private List<Integer> _armorSkins = new CopyOnWriteArrayList<>();
1726
+	private List<Integer> _weaponSkins = new CopyOnWriteArrayList<>();
1727
+	private List<Integer> _hairSkins = new CopyOnWriteArrayList<>();
1728
+	private List<Integer> _faceSkins = new CopyOnWriteArrayList<>();
1729
+	private List<Integer> _shieldSkins = new CopyOnWriteArrayList<>();
1730
+	
1731
+	private static final String INSERT_OR_UPDATE_CHARACTER_DRESSME_DATA = "INSERT INTO characters_dressme_data (obj_Id, armor_skins, armor_skin_option, weapon_skins, weapon_skin_option, hair_skins, hair_skin_option, face_skins, face_skin_option) VALUES (?,?,?,?,?,?,?,?,?) " + "ON DUPLICATE KEY UPDATE obj_Id=?, armor_skins=?, armor_skin_option=?, weapon_skins=?, weapon_skin_option=?, hair_skins=?, hair_skin_option=?, face_skins=?, face_skin_option=?, shield_skins=?, shield_skin_option=?";
1732
+	private static final String RESTORE_CHARACTER_DRESSME_DATA = "SELECT obj_Id, armor_skins, armor_skin_option, weapon_skins, weapon_skin_option, hair_skins, hair_skin_option, face_skins, face_skin_option, shield_skins, shield_skin_option FROM characters_dressme_data WHERE obj_id=?";
1733
+	
1734
 	private static final String RESTORE_SKILLS_FOR_CHAR = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? AND class_index=?";
1735
 	private static final String RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=?";
1736
 	private static final String ADD_OR_UPDATE_SKILL = "INSERT INTO character_skills (char_obj_id,skill_id,skill_level,class_index) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE skill_level=VALUES(skill_level)";
1737
@@ -1291,6 +1314,22 @@
1738
 		if (item.getItem() instanceof Weapon)
1739
 			item.unChargeAllShots();
1740
 		
1741
+		if (getWeaponSkinOption() > 0 && DressMeData.getInstance().getWeaponSkinsPackage(getWeaponSkinOption()) != null)
1742
+		{
1743
+			sendMessage("At first you must to remove a skin of weapon.");
1744
+			sendPacket(new ExShowScreenMessage("At first you must to remove a skin of weapon.", 2000));
1745
+			sendPacket(new PlaySound("ItemSound3.sys_impossible"));
1746
+			return;
1747
+		}
1748
+		
1749
+		if (getShieldSkinOption() > 0 && DressMeData.getInstance().getShieldSkinsPackage(getShieldSkinOption()) != null)
1750
+		{
1751
+			sendMessage("At first you must to remove a skin of weapon.");
1752
+			sendPacket(new ExShowScreenMessage("At first you must to remove a skin of weapon.", 2000));
1753
+			sendPacket(new PlaySound("ItemSound3.sys_impossible"));
1754
+			return;
1755
+		}
1756
+		
1757
 		if (isEquipped)
1758
 		{
1759
 			if (item.getEnchantLevel() > 0)
1760
@@ -2924,7 +2963,7 @@
1761
 				
1762
 				if (Config.ANNOUNCE_KILL)
1763
 					World.toAllOnlinePlayers(SystemMessage.getSystemMessage(SystemMessageId.S1_S2).addString(Config.ANNOUNCE_PVP_MSG.replace("$killer", getName()).replace("$target", targetPlayer.getName())).addZoneName(targetPlayer.getPosition()));
1764
-			
1765
+				
1766
 				if (Config.ALLOW_PVP_REWARD)
1767
 				{
1768
 					for (int[] item : Config.PVP_REWARD_ITEM)
1769
@@ -4302,7 +4341,7 @@
1770
 					player.refreshWeightPenalty();
1771
 					player.refreshExpertisePenalty();
1772
 					player.refreshHennaList();
1773
-					
1774
+					player.restoreDressMeData();
1775
 					player.setOnlineStatus(true, false);
1776
 					player.setRunning(true);
1777
 					player.setStanding(true);
1778
@@ -4425,6 +4464,11 @@
1779
 	{
1780
 		_cachedData.store();
1781
 		
1782
+		if (!isTryingSkin() || !isTryingSkinPremium())
1783
+		{
1784
+			storeDressMeData();
1785
+		}
1786
+		
1787
 		storeCharBase();
1788
 		storeCharSub();
1789
 		storeEffect(storeActiveEffects);
1790
@@ -7800,7 +7844,6 @@
1791
 		sendPacket(ActionFailed.STATIC_PACKET);
1792
 	}
1793
 	
1794
-	
1795
 	public void tryOpenPrivateBuffStore()
1796
 	{
1797
 		if (canOpenPrivateStore(true))
1798
@@ -8043,18 +8086,447 @@
1799
 	{
1800
 		if (getClient() == null)
1801
 			return _hwid;
1802
-
1803
+		
1804
 		_hwid = getClient().getHWID();
1805
 		return _hwid;
1806
 	}
1807
 	
1808
 	private boolean _skinView;
1809
 	
1810
-	public void setDisableSkinView(boolean comm) {
1811
+	public void setDisableSkinView(boolean comm)
1812
+	{
1813
 		_skinView = comm;
1814
 	}
1815
 	
1816
-	public boolean isDisableSkinView() {
1817
+	public boolean isDisableSkinView()
1818
+	{
1819
 		return _skinView;
1820
 	}
1821
+	
1822
+	private synchronized void storeDressMeData()
1823
+	{
1824
+		
1825
+		try (Connection con = ConnectionPool.getConnection();
1826
+			PreparedStatement statement = con.prepareStatement(INSERT_OR_UPDATE_CHARACTER_DRESSME_DATA))
1827
+		{
1828
+			
1829
+			statement.setInt(1, getObjectId());
1830
+			if (_armorSkins.isEmpty())
1831
+			{
1832
+				statement.setString(2, "");
1833
+			}
1834
+			else
1835
+			{
1836
+				String s = "";
1837
+				for (int i : _armorSkins)
1838
+				{
1839
+					s += String.valueOf(i) + ",";
1840
+				}
1841
+				statement.setString(2, s);
1842
+			}
1843
+			statement.setInt(3, getArmorSkinOption());
1844
+			
1845
+			if (_weaponSkins.isEmpty())
1846
+			{
1847
+				statement.setString(4, "");
1848
+			}
1849
+			else
1850
+			{
1851
+				String s = "";
1852
+				for (int i : _weaponSkins)
1853
+				{
1854
+					s += String.valueOf(i) + ",";
1855
+				}
1856
+				statement.setString(4, s);
1857
+			}
1858
+			statement.setInt(5, getWeaponSkinOption());
1859
+			
1860
+			if (_hairSkins.isEmpty())
1861
+			{
1862
+				statement.setString(6, "");
1863
+			}
1864
+			else
1865
+			{
1866
+				String s = "";
1867
+				for (int i : _hairSkins)
1868
+				{
1869
+					s += String.valueOf(i) + ",";
1870
+				}
1871
+				statement.setString(6, s);
1872
+			}
1873
+			statement.setInt(7, getHairSkinOption());
1874
+			
1875
+			if (_faceSkins.isEmpty())
1876
+			{
1877
+				statement.setString(8, "");
1878
+			}
1879
+			else
1880
+			{
1881
+				String s = "";
1882
+				for (int i : _faceSkins)
1883
+				{
1884
+					s += String.valueOf(i) + ",";
1885
+				}
1886
+				statement.setString(8, s);
1887
+			}
1888
+			statement.setInt(9, getFaceSkinOption());
1889
+			
1890
+			if (_shieldSkins.isEmpty())
1891
+			{
1892
+				statement.setString(10, "");
1893
+			}
1894
+			else
1895
+			{
1896
+				String s = "";
1897
+				for (int i : _shieldSkins)
1898
+				{
1899
+					s += String.valueOf(i) + ",";
1900
+				}
1901
+				statement.setString(10, s);
1902
+			}
1903
+			statement.setInt(11, getShieldSkinOption());
1904
+			
1905
+			// second part
1906
+			
1907
+			statement.setInt(10, getObjectId());
1908
+			if (_armorSkins.isEmpty())
1909
+			{
1910
+				statement.setString(11, "");
1911
+			}
1912
+			else
1913
+			{
1914
+				String s = "";
1915
+				for (int i : _armorSkins)
1916
+				{
1917
+					s += String.valueOf(i) + ",";
1918
+				}
1919
+				statement.setString(11, s);
1920
+			}
1921
+			statement.setInt(12, getArmorSkinOption());
1922
+			
1923
+			if (_weaponSkins.isEmpty())
1924
+			{
1925
+				statement.setString(13, "");
1926
+			}
1927
+			else
1928
+			{
1929
+				String s = "";
1930
+				for (int i : _weaponSkins)
1931
+				{
1932
+					s += String.valueOf(i) + ",";
1933
+				}
1934
+				statement.setString(13, s);
1935
+			}
1936
+			statement.setInt(14, getWeaponSkinOption());
1937
+			
1938
+			if (_hairSkins.isEmpty())
1939
+			{
1940
+				statement.setString(15, "");
1941
+			}
1942
+			else
1943
+			{
1944
+				String s = "";
1945
+				for (int i : _hairSkins)
1946
+				{
1947
+					s += String.valueOf(i) + ",";
1948
+				}
1949
+				statement.setString(15, s);
1950
+			}
1951
+			statement.setInt(16, getHairSkinOption());
1952
+			
1953
+			if (_faceSkins.isEmpty())
1954
+			{
1955
+				statement.setString(17, "");
1956
+			}
1957
+			else
1958
+			{
1959
+				String s = "";
1960
+				for (int i : _faceSkins)
1961
+				{
1962
+					s += String.valueOf(i) + ",";
1963
+				}
1964
+				statement.setString(17, s);
1965
+			}
1966
+			statement.setInt(18, getFaceSkinOption());
1967
+			
1968
+			if (_shieldSkins.isEmpty())
1969
+			{
1970
+				statement.setString(19, "");
1971
+			}
1972
+			else
1973
+			{
1974
+				String s = "";
1975
+				for (int i : _shieldSkins)
1976
+				{
1977
+					s += String.valueOf(i) + ",";
1978
+				}
1979
+				statement.setString(19, s);
1980
+			}
1981
+			statement.setInt(20, getShieldSkinOption());
1982
+			
1983
+			statement.execute();
1984
+			
1985
+		}
1986
+		catch (Exception e)
1987
+		{
1988
+			
1989
+			LOGGER.warn("Could not store storeDressMeData():");
1990
+			e.printStackTrace();
1991
+			
1992
+		}
1993
+		
1994
+	}
1995
+	
1996
+	private void restoreDressMeData()
1997
+	{
1998
+		try (Connection con = ConnectionPool.getConnection();
1999
+			PreparedStatement statement = con.prepareStatement(RESTORE_CHARACTER_DRESSME_DATA))
2000
+		{
2001
+			
2002
+			statement.setInt(1, getObjectId()); // Establecer el parámetro objectId
2003
+			
2004
+			try (ResultSet rset = statement.executeQuery())
2005
+			{
2006
+				while (rset.next())
2007
+				{
2008
+					String armorskinIds = rset.getString("armor_skins");
2009
+					if (armorskinIds != null && armorskinIds.length() > 0)
2010
+					{
2011
+						for (String s : armorskinIds.split(","))
2012
+						{
2013
+							if (s == null)
2014
+							{
2015
+								continue;
2016
+							}
2017
+							buyArmorSkin(Integer.parseInt(s));
2018
+						}
2019
+					}
2020
+					setArmorSkinOption(rset.getInt("armor_skin_option"));
2021
+					
2022
+					String weaponskinIds = rset.getString("weapon_skins");
2023
+					if (weaponskinIds != null && weaponskinIds.length() > 0)
2024
+					{
2025
+						for (String s : weaponskinIds.split(","))
2026
+						{
2027
+							if (s == null)
2028
+							{
2029
+								continue;
2030
+							}
2031
+							buyWeaponSkin(Integer.parseInt(s));
2032
+						}
2033
+					}
2034
+					setWeaponSkinOption(rset.getInt("weapon_skin_option"));
2035
+					
2036
+					String hairskinIds = rset.getString("hair_skins");
2037
+					if (hairskinIds != null && hairskinIds.length() > 0)
2038
+					{
2039
+						for (String s : hairskinIds.split(","))
2040
+						{
2041
+							if (s == null)
2042
+							{
2043
+								continue;
2044
+							}
2045
+							buyHairSkin(Integer.parseInt(s));
2046
+						}
2047
+					}
2048
+					setHairSkinOption(rset.getInt("hair_skin_option"));
2049
+					
2050
+					String faceskinIds = rset.getString("face_skins");
2051
+					if (faceskinIds != null && faceskinIds.length() > 0)
2052
+					{
2053
+						for (String s : faceskinIds.split(","))
2054
+						{
2055
+							if (s == null)
2056
+							{
2057
+								continue;
2058
+							}
2059
+							buyFaceSkin(Integer.parseInt(s));
2060
+						}
2061
+					}
2062
+					setFaceSkinOption(rset.getInt("face_skin_option"));
2063
+					
2064
+					String shieldkinIds = rset.getString("shield_skins");
2065
+					if (shieldkinIds != null && shieldkinIds.length() > 0)
2066
+					{
2067
+						for (String s : shieldkinIds.split(","))
2068
+						{
2069
+							if (s == null)
2070
+							{
2071
+								continue;
2072
+							}
2073
+							buyShieldSkin(Integer.parseInt(s));
2074
+						}
2075
+					}
2076
+					setShieldSkinOption(rset.getInt("shield_skin_option"));
2077
+				}
2078
+			}
2079
+		}
2080
+		catch (Exception e)
2081
+		{
2082
+			LOGGER.warn("Could not restore char data:");
2083
+			e.printStackTrace();
2084
+		}
2085
+	}
2086
+	
2087
+	// Dress Me
2088
+	public boolean isTryingSkin()
2089
+	{
2090
+		return isTryingSkin;
2091
+	}
2092
+	
2093
+	public void setIsTryingSkin(boolean b)
2094
+	{
2095
+		isTryingSkin = b;
2096
+	}
2097
+	
2098
+	public boolean isTryingSkinPremium()
2099
+	{
2100
+		return isTryingSkinPremium;
2101
+	}
2102
+	
2103
+	public void setIsTryingSkinPremium(boolean b)
2104
+	{
2105
+		isTryingSkinPremium = b;
2106
+	}
2107
+	
2108
+	public boolean hasArmorSkin(int skin)
2109
+	{
2110
+		return _armorSkins.contains(skin);
2111
+	}
2112
+	
2113
+	public boolean hasWeaponSkin(int skin)
2114
+	{
2115
+		return _weaponSkins.contains(skin);
2116
+	}
2117
+	
2118
+	public boolean hasHairSkin(int skin)
2119
+	{
2120
+		return _hairSkins.contains(skin);
2121
+	}
2122
+	
2123
+	public boolean hasFaceSkin(int skin)
2124
+	{
2125
+		return _faceSkins.contains(skin);
2126
+	}
2127
+	
2128
+	public boolean hasShieldSkin(int skin)
2129
+	{
2130
+		return _shieldSkins.contains(skin);
2131
+	}
2132
+	
2133
+	public boolean hasEquippedArmorSkin(String skin)
2134
+	{
2135
+		return String.valueOf(_armorSkinOption).contains(String.valueOf(skin));
2136
+	}
2137
+	
2138
+	public boolean hasEquippedWeaponSkin(String skin)
2139
+	{
2140
+		return String.valueOf(_weaponSkinOption).contains(String.valueOf(skin));
2141
+	}
2142
+	
2143
+	public boolean hasEquippedHairSkin(String skin)
2144
+	{
2145
+		return String.valueOf(_hairSkinOption).contains(String.valueOf(skin));
2146
+	}
2147
+	
2148
+	public boolean hasEquippedFaceSkin(String skin)
2149
+	{
2150
+		return String.valueOf(_faceSkinOption).contains(String.valueOf(skin));
2151
+	}
2152
+	
2153
+	public boolean hasEquippedShieldSkin(String skin)
2154
+	{
2155
+		return String.valueOf(_shieldSkinOption).contains(String.valueOf(skin));
2156
+	}
2157
+	
2158
+	public void buyArmorSkin(int id)
2159
+	{
2160
+		if (!_armorSkins.contains(id))
2161
+		{
2162
+			_armorSkins.add(id);
2163
+		}
2164
+	}
2165
+	
2166
+	public void buyWeaponSkin(int id)
2167
+	{
2168
+		if (!_weaponSkins.contains(id))
2169
+		{
2170
+			_weaponSkins.add(id);
2171
+		}
2172
+	}
2173
+	
2174
+	public void buyHairSkin(int id)
2175
+	{
2176
+		if (!_hairSkins.contains(id))
2177
+		{
2178
+			_hairSkins.add(id);
2179
+		}
2180
+	}
2181
+	
2182
+	public void buyFaceSkin(int id)
2183
+	{
2184
+		if (!_faceSkins.contains(id))
2185
+		{
2186
+			_faceSkins.add(id);
2187
+		}
2188
+	}
2189
+	
2190
+	public void buyShieldSkin(int id)
2191
+	{
2192
+		if (!_shieldSkins.contains(id))
2193
+		{
2194
+			_shieldSkins.add(id);
2195
+		}
2196
+	}
2197
+	
2198
+	public void setArmorSkinOption(int armorSkinOption)
2199
+	{
2200
+		_armorSkinOption = armorSkinOption;
2201
+	}
2202
+	
2203
+	public int getArmorSkinOption()
2204
+	{
2205
+		return _armorSkinOption;
2206
+	}
2207
+	
2208
+	public void setWeaponSkinOption(int weaponSkinOption)
2209
+	{
2210
+		_weaponSkinOption = weaponSkinOption;
2211
+	}
2212
+	
2213
+	public int getWeaponSkinOption()
2214
+	{
2215
+		return _weaponSkinOption;
2216
+	}
2217
+	
2218
+	public void setHairSkinOption(int hairSkinOption)
2219
+	{
2220
+		_hairSkinOption = hairSkinOption;
2221
+	}
2222
+	
2223
+	public int getHairSkinOption()
2224
+	{
2225
+		return _hairSkinOption;
2226
+	}
2227
+	
2228
+	public void setFaceSkinOption(int faceSkinOption)
2229
+	{
2230
+		_faceSkinOption = faceSkinOption;
2231
+	}
2232
+	
2233
+	public int getFaceSkinOption()
2234
+	{
2235
+		return _faceSkinOption;
2236
+	}
2237
+	
2238
+	public void setShieldSkinOption(int shieldSkinOption)
2239
+	{
2240
+		_shieldSkinOption = shieldSkinOption;
2241
+	}
2242
+	
2243
+	public int getShieldSkinOption()
2244
+	{
2245
+		return _shieldSkinOption;
2246
+	}
2247
+	
2248
 }
2249
\ No newline at end of file
2250
diff --git java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
2251
index c99ef59..57bdbe0 100644
2252
--- java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
2253
+++ java/net/sf/l2j/gameserver/network/clientpackets/EnterWorld.java
2254
@@ -1,10 +1,14 @@
2255
 package net.sf.l2j.gameserver.network.clientpackets;
2256
 
2257
+import java.sql.Connection;
2258
+import java.sql.PreparedStatement;
2259
+import java.sql.ResultSet;
2260
 import java.text.SimpleDateFormat;
2261
 import java.util.Date;
2262
 import java.util.Map;
2263
 import java.util.Map.Entry;
2264
 
2265
+import net.sf.l2j.commons.pool.ConnectionPool;
2266
 import net.sf.l2j.commons.pool.ThreadPool;
2267
 
2268
 import net.sf.l2j.Config;
2269
@@ -125,6 +129,13 @@
2270
 		player.updateEffectIcons();
2271
 		player.sendPacket(new EtcStatusUpdate(player));
2272
 		
2273
+		if (Config.ALLOW_DRESS_ME_SYSTEM)
2274
+		
2275
+		{
2276
+			
2277
+			checkskin(player, player.getObjectId(), player.getArmorSkinOption(), player.getWeaponSkinOption(), player.getHairSkinOption(), player.getFaceSkinOption(), player.getShieldSkinOption());
2278
+		}
2279
+		
2280
 		// Clan checks.
2281
 		final Clan clan = player.getClan();
2282
 		if (clan != null)
2283
@@ -370,6 +381,60 @@
2284
 		player.sendMessage(player.getSysString(10_046, df.format(dt)));
2285
 	}
2286
 	
2287
+	private static void checkskin(Player player, final int objectId, int armorid, int weaponid, int hairid, int faceid, int shieldid)
2288
+	{
2289
+		try (Connection con = ConnectionPool.getConnection();
2290
+			PreparedStatement statement = con.prepareStatement("SELECT obj_Id, armor_skins, armor_skin_option, weapon_skins, weapon_skin_option, hair_skins, hair_skin_option, face_skins, face_skin_option FROM characters_dressme_data WHERE obj_Id=?"))
2291
+		{
2292
+			
2293
+			statement.setInt(1, objectId);
2294
+			try (ResultSet chardata = statement.executeQuery())
2295
+			{
2296
+				if (chardata.next())
2297
+				{
2298
+					// Comprobación de skin de armadura
2299
+					String armorSkins = chardata.getString("armor_skins");
2300
+					if (!armorSkins.contains(String.valueOf(armorid)))
2301
+					{
2302
+						armorid = 0; // Si el skin de armadura no está en la lista, establece a 0
2303
+					}
2304
+					
2305
+					// Comprobación de skin de arma
2306
+					String weaponSkins = chardata.getString("weapon_skins");
2307
+					if (!weaponSkins.contains(String.valueOf(weaponid)))
2308
+					{
2309
+						weaponid = 0; // Si el skin de arma no está en la lista, establece a 0
2310
+					}
2311
+					
2312
+					// Comprobación de skin de cabello
2313
+					String hairSkins = chardata.getString("hair_skins");
2314
+					if (!hairSkins.contains(String.valueOf(hairid)))
2315
+					{
2316
+						hairid = 0; // Si el skin de cabello no está en la lista, establece a 0
2317
+					}
2318
+					
2319
+					// Comprobación de skin de cara
2320
+					String faceSkins = chardata.getString("face_skins");
2321
+					if (!faceSkins.contains(String.valueOf(faceid)))
2322
+					{
2323
+						faceid = 0; // Si el skin de cara no está en la lista, establece a 0
2324
+					}
2325
+					
2326
+					// Aplicar las opciones de skin al jugador
2327
+					player.setArmorSkinOption(armorid);
2328
+					player.setWeaponSkinOption(weaponid);
2329
+					player.setHairSkinOption(hairid);
2330
+					player.setFaceSkinOption(faceid);
2331
+					player.setShieldSkinOption(shieldid);
2332
+				}
2333
+			}
2334
+		}
2335
+		catch (final Exception e)
2336
+		{
2337
+			e.printStackTrace();
2338
+		}
2339
+	}
2340
+	
2341
 	@Override
2342
 	protected boolean triggersOnActionRequest()
2343
 	{
2344
diff --git java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
2345
index 3c744ac..0c7d755 100644
2346
--- java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
2347
+++ java/net/sf/l2j/gameserver/network/clientpackets/RequestBypassToServer.java
2348
@@ -1,20 +1,26 @@
2349
 package net.sf.l2j.gameserver.network.clientpackets;
2350
 
2351
+import java.sql.Date;
2352
 import java.text.DecimalFormat;
2353
+import java.text.SimpleDateFormat;
2354
 import java.util.Arrays;
2355
 import java.util.Comparator;
2356
+import java.util.List;
2357
 import java.util.Map;
2358
 import java.util.StringTokenizer;
2359
 import java.util.logging.Logger;
2360
 import java.util.stream.Collectors;
2361
+import java.util.stream.Stream;
2362
 
2363
 import net.sf.l2j.commons.data.Pagination;
2364
 import net.sf.l2j.commons.lang.StringUtil;
2365
+import net.sf.l2j.commons.pool.ThreadPool;
2366
 
2367
 import net.sf.l2j.Config;
2368
 import net.sf.l2j.gameserver.communitybbs.CommunityBoard;
2369
 import net.sf.l2j.gameserver.communitybbs.CustomCommunityBoard;
2370
 import net.sf.l2j.gameserver.data.DropCalc;
2371
+import net.sf.l2j.gameserver.data.HTMLData;
2372
+import net.sf.l2j.gameserver.handler.CustomBypassHandler;
2373
 import net.sf.l2j.gameserver.data.manager.BotsPreventionManager;
2374
 import net.sf.l2j.gameserver.data.manager.HeroManager;
2375
 import net.sf.l2j.gameserver.data.manager.SpawnManager;
2376
@@ -22,7 +28,9 @@
2377
 import net.sf.l2j.gameserver.data.xml.ItemData;
2378
 import net.sf.l2j.gameserver.enums.DropType;
2379
 import net.sf.l2j.gameserver.enums.FloodProtector;
2380
+import net.sf.l2j.gameserver.enums.ZoneId;
2381
 import net.sf.l2j.gameserver.enums.actors.NpcSkillType;
2382
+import net.sf.l2j.gameserver.enums.items.WeaponType;
2383
 import net.sf.l2j.gameserver.enums.skills.ElementType;
2384
 import net.sf.l2j.gameserver.enums.skills.SkillType;
2385
 import net.sf.l2j.gameserver.handler.AdminCommandHandler;
2386
@@ -40,18 +48,24 @@
2387
 import net.sf.l2j.gameserver.model.actor.instance.OlympiadManagerNpc;
2388
 import net.sf.l2j.gameserver.model.item.DropCategory;
2389
 import net.sf.l2j.gameserver.model.item.DropData;
2390
+import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
2391
 import net.sf.l2j.gameserver.model.item.kind.Item;
2392
 import net.sf.l2j.gameserver.model.olympiad.OlympiadManager;
2393
 import net.sf.l2j.gameserver.model.spawn.ASpawn;
2394
 import net.sf.l2j.gameserver.network.SystemMessageId;
2395
 import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
2396
+import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
2397
 import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
2398
+import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
2399
 import net.sf.l2j.gameserver.scripting.QuestState;
2400
 import net.sf.l2j.gameserver.skills.AbstractEffect;
2401
 import net.sf.l2j.gameserver.skills.L2Skill;
2402
 
2403
+import Base.Data.IconTable;
2404
 import Base.Roullete.RouletteData;
2405
 import Base.Roullete.RouletteManager;
2406
+import Base.Skin.DressMeData;
2407
+import Base.Skin.SkinPackage;
2408
 
2409
 public final class RequestBypassToServer extends L2GameClientPacket
2410
 {
2411
@@ -135,6 +149,415 @@
2412
 			new RouletteManager(player);
2413
 		}
2414
 		
2415
		
2416
+		else if (_command.startsWith("custom_"))
2417
+		{
2418
+			
2419
+			CustomBypassHandler.getInstance().handleBypass(player, _command);
2420
+		}
2421
+		
2422
+		
2423
+		else if (_command.startsWith("dressme"))
2424
+		{
2425
+			if (!Config.ALLOW_DRESS_ME_IN_OLY && player.isInOlympiadMode())
2426
+			{
2427
+				player.sendMessage("DressMe can't be used on The Olympiad game.");
2428
+				return;
2429
+			}
2430
+			
2431
+			StringTokenizer st = new StringTokenizer(_command, " ");
2432
+			st.nextToken();
2433
+			if (!st.hasMoreTokens())
2434
+			{
2435
+				showDressMeMainPage(player);
2436
+				return;
2437
+			}
2438
+			int page = Integer.parseInt(st.nextToken());
2439
+			
2440
+			if (!st.hasMoreTokens())
2441
+			{
2442
+				showDressMeMainPage(player);
2443
+				return;
2444
+			}
2445
+			String next = st.nextToken();
2446
+			if (next.startsWith("skinlist"))
2447
+			{
2448
+				String type = st.nextToken();
2449
+				showSkinList(player, type, page);
2450
+			}
2451
+			else if (next.startsWith("myskinlist"))
2452
+			{
2453
+				
2454
+				showMySkinList(player, page);
2455
+			}
2456
+			if (next.equals("clean"))
2457
+			{
2458
+				String type = st.nextToken();
2459
+				
2460
+				if (player.isTryingSkin())
2461
+				{
2462
+					player.sendMessage("You can't do this while trying a skin.");
2463
+					player.sendPacket(new ExShowScreenMessage("You can't do this while trying a skin.", 2000));
2464
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2465
+					showDressMeMainPage(player);
2466
+					return;
2467
+				}
2468
+				
2469
+				switch (type.toLowerCase())
2470
+				{
2471
+					case "armor":
2472
+						player.setArmorSkinOption(0);
2473
+						break;
2474
+					case "weapon":
2475
+						player.setWeaponSkinOption(0);
2476
+						break;
2477
+					case "hair":
2478
+						player.setHairSkinOption(0);
2479
+						break;
2480
+					case "face":
2481
+						player.setFaceSkinOption(0);
2482
+						break;
2483
+					case "shield":
2484
+						player.setShieldSkinOption(0);
2485
+						break;
2486
+				}
2487
+				
2488
+				player.broadcastUserInfo();
2489
+				showMySkinList(player, page);
2490
+			}
2491
+			else if (next.startsWith("buyskin"))
2492
+			{
2493
+				if (!st.hasMoreTokens())
2494
+				{
2495
+					showDressMeMainPage(player);
2496
+					return;
2497
+				}
2498
+				
2499
+				int skinId = Integer.parseInt(st.nextToken());
2500
+				String type = st.nextToken();
2501
+				int itemId = Integer.parseInt(st.nextToken());
2502
+				if (!player.isInsideZone(ZoneId.TOWN))
2503
+				{
2504
+					
2505
+					player.sendMessage("Solo Puedes Comprar Skin En Ciudad.");
2506
+					player.sendPacket(new ExShowScreenMessage("Solo Puedes Comprar Skin En Ciudad.", 2000));
2507
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2508
+					showSkinList(player, type, page);
2509
+					return;
2510
+				}
2511
+				
2512
+				SkinPackage sp = null;
2513
+				
2514
+				switch (type.toLowerCase())
2515
+				{
2516
+					case "armor":
2517
+						sp = DressMeData.getInstance().getArmorSkinsPackage(skinId);
2518
+						break;
2519
+					case "weapon":
2520
+						sp = DressMeData.getInstance().getWeaponSkinsPackage(skinId);
2521
+						
2522
+						if (player.getActiveWeaponItem() == null)
2523
+						{
2524
+							player.sendMessage("You can't buy this skin without a weapon.");
2525
+							player.sendPacket(new ExShowScreenMessage("You can't buy this skin without a weapon.", 2000));
2526
+							player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2527
+							showSkinList(player, type, page);
2528
+							return;
2529
+						}
2530
+						
2531
+						ItemInstance skinWeapon = null;
2532
+						if (ItemData.getInstance().getTemplate(itemId) != null)
2533
+						{
2534
+							skinWeapon = ItemData.getInstance().createDummyItem(itemId);
2535
+							
2536
+							if (!checkWeapons(player, skinWeapon, WeaponType.BOW, WeaponType.BOW) //
2537
+								|| !checkWeapons(player, skinWeapon, WeaponType.SWORD, WeaponType.SWORD) //
2538
+								|| !checkWeapons(player, skinWeapon, WeaponType.BLUNT, WeaponType.BLUNT) //
2539
+								|| !checkWeapons(player, skinWeapon, WeaponType.DAGGER, WeaponType.DAGGER) //
2540
+								|| !checkWeapons(player, skinWeapon, WeaponType.POLE, WeaponType.POLE) //
2541
+								|| !checkWeapons(player, skinWeapon, WeaponType.DUAL, WeaponType.DUAL) //
2542
+								|| !checkWeapons(player, skinWeapon, WeaponType.DUALFIST, WeaponType.DUALFIST) //
2543
+								|| !checkWeapons(player, skinWeapon, WeaponType.BIGSWORD, WeaponType.BIGSWORD) //
2544
+								|| !checkWeapons(player, skinWeapon, WeaponType.FIST, WeaponType.FIST) //
2545
+								|| !checkWeapons(player, skinWeapon, WeaponType.BIGBLUNT, WeaponType.BIGBLUNT))
2546
+							{
2547
+								player.sendMessage("This skin is not suitable for your weapon type.");
2548
+								player.sendPacket(new ExShowScreenMessage("This skin is not suitable for your weapon type.", 2000));
2549
+								player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2550
+								showSkinList(player, type, page);
2551
+								return;
2552
+							}
2553
+						}
2554
+						break;
2555
+					case "hair":
2556
+						sp = DressMeData.getInstance().getHairSkinsPackage(skinId);
2557
+						break;
2558
+					case "face":
2559
+						sp = DressMeData.getInstance().getFaceSkinsPackage(skinId);
2560
+						break;
2561
+					case "shield":
2562
+						sp = DressMeData.getInstance().getShieldSkinsPackage(skinId);
2563
+						if (player.getActiveWeaponItem() == null)
2564
+						{
2565
+							player.sendMessage("You can't buy this skin without a weapon.");
2566
+							player.sendPacket(new ExShowScreenMessage("You can't buy this skin without a weapon.", 2000));
2567
+							player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2568
+							showSkinList(player, type, page);
2569
+							return;
2570
+						}
2571
+						
2572
+						ItemInstance skinShield = null;
2573
+						if (ItemData.getInstance().getTemplate(itemId) != null)
2574
+						{
2575
+							skinShield = ItemData.getInstance().createDummyItem(itemId);
2576
+							
2577
+							if (!checkWeapons(player, skinShield, WeaponType.BOW, WeaponType.BOW) //
2578
+								|| !checkWeapons(player, skinShield, WeaponType.POLE, WeaponType.POLE) //
2579
+								|| !checkWeapons(player, skinShield, WeaponType.DUAL, WeaponType.DUAL) //
2580
+								|| !checkWeapons(player, skinShield, WeaponType.DUALFIST, WeaponType.DUALFIST) //
2581
+								|| !checkWeapons(player, skinShield, WeaponType.BIGSWORD, WeaponType.BIGSWORD) //
2582
+								|| !checkWeapons(player, skinShield, WeaponType.FIST, WeaponType.FIST) //
2583
+								|| !checkWeapons(player, skinShield, WeaponType.BIGBLUNT, WeaponType.BIGBLUNT))
2584
+							{
2585
+								player.sendMessage("This skin is not suitable for your weapon type.");
2586
+								player.sendPacket(new ExShowScreenMessage("This skin is not suitable for your weapon type.", 2000));
2587
+								player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2588
+								showSkinList(player, type, page);
2589
+								return;
2590
+							}
2591
+						}
2592
+						break;
2593
+				}
2594
+				
2595
+				if (sp == null)
2596
+				{
2597
+					player.sendMessage("There is no such skin.");
2598
+					player.sendPacket(new ExShowScreenMessage("There is no such skin.", 2000));
2599
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2600
+					showSkinList(player, type, page);
2601
+					return;
2602
+				}
2603
+				
2604
+				if (player.destroyItemByItemId(sp.getPriceId(), sp.getPriceCount(), true))
2605
+				{
2606
+					player.sendMessage("You have successfully purchased " + sp.getName() + " skin.");
2607
+					player.sendPacket(new ExShowScreenMessage("You have successfully purchased " + sp.getName() + " skin.", 2000));
2608
+					
2609
+					switch (type.toLowerCase())
2610
+					{
2611
+						case "armor":
2612
+							player.buyArmorSkin(skinId);
2613
+							player.setArmorSkinOption(skinId);
2614
+							break;
2615
+						case "weapon":
2616
+							player.buyWeaponSkin(skinId);
2617
+							player.setWeaponSkinOption(skinId);
2618
+							break;
2619
+						case "hair":
2620
+							player.buyHairSkin(skinId);
2621
+							player.setHairSkinOption(skinId);
2622
+							break;
2623
+						case "face":
2624
+							player.buyFaceSkin(skinId);
2625
+							player.setFaceSkinOption(skinId);
2626
+							break;
2627
+						case "shield":
2628
+							player.buyShieldSkin(skinId);
2629
+							player.setShieldSkinOption(skinId);
2630
+							break;
2631
+					}
2632
+					
2633
+					player.broadcastUserInfo();
2634
+				}
2635
+				showSkinList(player, type, page);
2636
+			}
2637
+			else if (next.startsWith("tryskin"))
2638
+			{
2639
+				
2640
+				int skinId = Integer.parseInt(st.nextToken());
2641
+				
2642
+				String type = st.nextToken();
2643
+				
2644
+				if (player.isTryingSkin())
2645
+				{
2646
+					player.sendMessage("You are already trying a skin.");
2647
+					player.sendPacket(new ExShowScreenMessage("You are already trying a skin.", 2000));
2648
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2649
+					showSkinList(player, type, page);
2650
+					return;
2651
+				}
2652
+				
2653
+				player.setIsTryingSkin(true);
2654
+				
2655
+				int oldArmorSkinId = player.getArmorSkinOption();
2656
+				int oldWeaponSkinId = player.getWeaponSkinOption();
2657
+				int oldHairSkinId = player.getHairSkinOption();
2658
+				int oldFaceSkinId = player.getFaceSkinOption();
2659
+				int oldShieldSkinId = player.getShieldSkinOption();
2660
+				
2661
+				switch (type.toLowerCase())
2662
+				{
2663
+					case "armor":
2664
+						player.setArmorSkinOption(skinId);
2665
+						break;
2666
+					case "weapon":
2667
+						player.setWeaponSkinOption(skinId);
2668
+						break;
2669
+					case "hair":
2670
+						player.setHairSkinOption(skinId);
2671
+						break;
2672
+					case "face":
2673
+						player.setFaceSkinOption(skinId);
2674
+						break;
2675
+					case "shield":
2676
+						
2677
+						player.setShieldSkinOption(skinId);
2678
+						
2679
+						break;
2680
+				}
2681
+				
2682
+				player.broadcastUserInfo();
2683
+				showSkinList(player, type, page);
2684
+				
2685
+				ThreadPool.schedule(() ->
2686
+				{
2687
+					switch (type.toLowerCase())
2688
+					{
2689
+						case "armor":
2690
+							player.setArmorSkinOption(oldArmorSkinId);
2691
+							break;
2692
+						case "weapon":
2693
+							player.setWeaponSkinOption(oldWeaponSkinId);
2694
+							break;
2695
+						case "hair":
2696
+							player.setHairSkinOption(oldHairSkinId);
2697
+							break;
2698
+						case "face":
2699
+							player.setFaceSkinOption(oldFaceSkinId);
2700
+							break;
2701
+						case "shield":
2702
+							player.setShieldSkinOption(oldShieldSkinId);
2703
+							break;
2704
+					}
2705
+					
2706
+					player.broadcastUserInfo();
2707
+					player.setIsTryingSkin(false);
2708
+				}, 5000);
2709
+			}
2710
+			else if (next.startsWith("setskin"))
2711
+			{
2712
+				int id = Integer.parseInt(st.nextToken());
2713
+				String type = st.nextToken();
2714
+				int itemId = Integer.parseInt(st.nextToken());
2715
+				
2716
+				if (player.isTryingSkin())
2717
+				{
2718
+					player.sendMessage("You can't do this while trying skins.");
2719
+					player.sendPacket(new ExShowScreenMessage("You can't do this while trying skins.", 2000));
2720
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2721
+					showMySkinList(player, page);
2722
+					return;
2723
+				}
2724
+				if (!player.isInsideZone(ZoneId.TOWN))
2725
+				{
2726
+					
2727
+					player.sendMessage("Solo Puedes Equiparte La Skin En Ciudad.");
2728
+					player.sendPacket(new ExShowScreenMessage("Solo Puedes Equiparte La Skin En Ciudad.", 2000));
2729
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2730
+					showSkinList(player, type, page);
2731
+					return;
2732
+				}
2733
+				
2734
+				if (type.toLowerCase().contains("armor") && player.hasEquippedArmorSkin(String.valueOf(id)) || type.toLowerCase().contains("weapon") && player.hasEquippedWeaponSkin(String.valueOf(id)) || type.toLowerCase().contains("hair") && player.hasEquippedHairSkin(String.valueOf(id)) || type.toLowerCase().contains("face") && player.hasEquippedFaceSkin(String.valueOf(id)))
2735
+				{
2736
+					player.sendMessage("You are already equipped this skin.");
2737
+					player.sendPacket(new ExShowScreenMessage("You are already equipped this skin.", 2000));
2738
+					player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2739
+					showMySkinList(player, page);
2740
+					return;
2741
+				}
2742
+				
2743
+				switch (type.toLowerCase())
2744
+				{
2745
+					case "armor":
2746
+						player.setArmorSkinOption(id);
2747
+						break;
2748
+					case "weapon":
2749
+						if (player.getActiveWeaponItem() == null)
2750
+						{
2751
+							player.sendMessage("You can't use this skin without a weapon.");
2752
+							player.sendPacket(new ExShowScreenMessage("You can't use this skin without a weapon.", 2000));
2753
+							player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2754
+							showMySkinList(player, page);
2755
+							return;
2756
+						}
2757
+						
2758
+						ItemInstance skinWeapon = null;
2759
+						if (ItemData.getInstance().getTemplate(itemId) != null)
2760
+						{
2761
+							skinWeapon = ItemData.getInstance().createDummyItem(itemId);
2762
+							
2763
+							if (!checkWeapons(player, skinWeapon, WeaponType.BOW, WeaponType.BOW) //
2764
+								|| !checkWeapons(player, skinWeapon, WeaponType.SWORD, WeaponType.SWORD) //
2765
+								|| !checkWeapons(player, skinWeapon, WeaponType.BLUNT, WeaponType.BLUNT) //
2766
+								|| !checkWeapons(player, skinWeapon, WeaponType.DAGGER, WeaponType.DAGGER) //
2767
+								|| !checkWeapons(player, skinWeapon, WeaponType.POLE, WeaponType.POLE) //
2768
+								|| !checkWeapons(player, skinWeapon, WeaponType.DUAL, WeaponType.DUAL) //
2769
+								|| !checkWeapons(player, skinWeapon, WeaponType.DUALFIST, WeaponType.DUALFIST) //
2770
+								|| !checkWeapons(player, skinWeapon, WeaponType.BIGSWORD, WeaponType.BIGSWORD) //
2771
+								|| !checkWeapons(player, skinWeapon, WeaponType.FIST, WeaponType.FIST) //
2772
+								|| !checkWeapons(player, skinWeapon, WeaponType.BIGBLUNT, WeaponType.BIGBLUNT))
2773
+							{
2774
+								player.sendMessage("This skin is not suitable for your weapon type.");
2775
+								player.sendPacket(new ExShowScreenMessage("This skin is not suitable for your weapon type.", 2000));
2776
+								player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2777
+								showMySkinList(player, page);
2778
+								return;
2779
+							}
2780
+							
2781
+							player.setWeaponSkinOption(id);
2782
+						}
2783
+						break;
2784
+					case "hair":
2785
+						player.setHairSkinOption(id);
2786
+						break;
2787
+					case "face":
2788
+						player.setFaceSkinOption(id);
2789
+						break;
2790
+					case "shield":
2791
+						if (player.getActiveWeaponItem() == null)
2792
+						{
2793
+							player.sendMessage("You can't use this skin without a weapon.");
2794
+							player.sendPacket(new ExShowScreenMessage("You can't use this skin without a weapon.", 2000));
2795
+							player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2796
+							showMySkinList(player, page);
2797
+							return;
2798
+						}
2799
+						
2800
+						ItemInstance skinShield = null;
2801
+						if (ItemData.getInstance().getTemplate(itemId) != null)
2802
+						{
2803
+							skinShield = ItemData.getInstance().createDummyItem(itemId);
2804
+							
2805
+							if (!checkWeapons(player, skinShield, WeaponType.BOW, WeaponType.BOW) //
2806
+								|| !checkWeapons(player, skinShield, WeaponType.POLE, WeaponType.POLE) //
2807
+								|| !checkWeapons(player, skinShield, WeaponType.DUAL, WeaponType.DUAL) //
2808
+								|| !checkWeapons(player, skinShield, WeaponType.DUALFIST, WeaponType.DUALFIST) //
2809
+								|| !checkWeapons(player, skinShield, WeaponType.BIGSWORD, WeaponType.BIGSWORD) //
2810
+								|| !checkWeapons(player, skinShield, WeaponType.FIST, WeaponType.FIST) //
2811
+								|| !checkWeapons(player, skinShield, WeaponType.BIGBLUNT, WeaponType.BIGBLUNT))
2812
+							{
2813
+								player.sendMessage("This skin is not suitable for your weapon type.");
2814
+								player.sendPacket(new ExShowScreenMessage("This skin is not suitable for your weapon type.", 2000));
2815
+								player.sendPacket(new PlaySound("ItemSound3.sys_impossible"));
2816
+								showMySkinList(player, page);
2817
+								return;
2818
+							}
2819
+							
2820
+							player.setShieldSkinOption(id);
2821
+						}
2822
+						
2823
+						break;
2824
+				}
2825
+				
2826
+				player.broadcastUserInfo();
2827
+				showMySkinList(player, page);
2828
+			}
2829
+			
2830
+		}
2831
+		
2832
 		else if (_command.startsWith("player_help "))
2833
 		{
2834
 			final String path = _command.substring(12);
2835
@@ -627,4 +1050,261 @@
2836
 		}
2837
 	}
2838
 	
2839
+	public static String getItemNameById(int itemId)
2840
+	{
2841
+		Item item = ItemData.getInstance().getTemplate(itemId);
2842
+		
2843
+		String itemName = "NoName";
2844
+		
2845
+		if (itemId != 0)
2846
+		{
2847
+			itemName = item.getName();
2848
+		}
2849
+		
2850
+		return itemName;
2851
+	}
2852
+	
2853
+	public static void showDressMeMainPage(Player player)
2854
+	{
2855
+		NpcHtmlMessage htm = new NpcHtmlMessage(1);
2856
+		String text = HTMLData.getInstance().getHtm(player.getLocale(), "html/dressme/index.htm");
2857
+		
2858
+		htm.setHtml(text);
2859
+		
2860
+		{
2861
+			htm.replace("%time%", sdf.format(new Date(System.currentTimeMillis())));
2862
+			htm.replace("%dat%", (new SimpleDateFormat("dd/MM/yyyy")).format(new Date(System.currentTimeMillis())));
2863
+			
2864
+		}
2865
+		
2866
+		player.sendPacket(htm);
2867
+	}
2868
+	
2869
+	static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
2870
+	
2871
+	private static void showSkinList(Player player, String type, int page)
2872
+	{
2873
+		NpcHtmlMessage html = new NpcHtmlMessage(1);
2874
+		
2875
+		html.setFile(player.getLocale(), "html/dressme/allskins.htm");
2876
+		
2877
+		html.replace("%time%", sdf.format(new Date(System.currentTimeMillis())));
2878
+		html.replace("%dat%", (new SimpleDateFormat("dd/MM/yyyy")).format(new Date(System.currentTimeMillis())));
2879
+		
2880
+		final int ITEMS_PER_PAGE = 8;
2881
+		
2882
+		int myPage = 1;
2883
+		int i = 0;
2884
+		int shown = 0;
2885
+		boolean hasMore = false;
2886
+		int itemId = 0;
2887
+		
2888
+		final StringBuilder sb = new StringBuilder();
2889
+		
2890
+		List<SkinPackage> tempList = null;
2891
+		switch (type.toLowerCase())
2892
+		{
2893
+			case "armor":
2894
+				tempList = DressMeData.getInstance().getArmorSkinOptions().values().stream().filter(s -> !player.hasArmorSkin(s.getId())).collect(Collectors.toList());
2895
+				break;
2896
+			case "weapon":
2897
+				tempList = DressMeData.getInstance().getWeaponSkinOptions().values().stream().filter(s -> !player.hasWeaponSkin(s.getId())).collect(Collectors.toList());
2898
+				break;
2899
+			case "hair":
2900
+				tempList = DressMeData.getInstance().getHairSkinOptions().values().stream().filter(s -> !player.hasHairSkin(s.getId())).collect(Collectors.toList());
2901
+				break;
2902
+			case "face":
2903
+				tempList = DressMeData.getInstance().getFaceSkinOptions().values().stream().filter(s -> !player.hasFaceSkin(s.getId())).collect(Collectors.toList());
2904
+				break;
2905
+			case "shield":
2906
+				tempList = DressMeData.getInstance().getShieldSkinOptions().values().stream().filter(s -> !player.hasShieldSkin(s.getId())).collect(Collectors.toList());
2907
+				break;
2908
+		}
2909
+		
2910
+		if (tempList != null && !tempList.isEmpty())
2911
+		{
2912
+			for (SkinPackage sp : tempList)
2913
+			{
2914
+				if (sp == null)
2915
+				{
2916
+					continue;
2917
+				}
2918
+				
2919
+				if (shown == ITEMS_PER_PAGE)
2920
+				{
2921
+					hasMore = true;
2922
+					break;
2923
+				}
2924
+				
2925
+				if (myPage != page)
2926
+				{
2927
+					i++;
2928
+					if (i == ITEMS_PER_PAGE)
2929
+					{
2930
+						myPage++;
2931
+						i = 0;
2932
+					}
2933
+					continue;
2934
+				}
2935
+				
2936
+				if (shown == ITEMS_PER_PAGE)
2937
+				{
2938
+					hasMore = true;
2939
+					break;
2940
+				}
2941
+				
2942
+				switch (type.toLowerCase())
2943
+				{
2944
+					case "armor":
2945
+						itemId = sp.getChestId();
2946
+						break;
2947
+					case "weapon":
2948
+						itemId = sp.getWeaponId();
2949
+						break;
2950
+					case "hair":
2951
+						itemId = sp.getHairId();
2952
+						break;
2953
+					case "face":
2954
+						itemId = sp.getFaceId();
2955
+						break;
2956
+					case "shield":
2957
+						itemId = sp.getShieldId();
2958
+						break;
2959
+				}
2960
+				
2961
+				sb.append("<table border=0 cellspacing=0 cellpadding=2 height=36><tr>");
2962
+				sb.append("<td width=32 align=center>" + "<button width=32 height=32 back=" + IconTable.getIcon(itemId) + " fore=" + IconTable.getIcon(itemId) + ">" + "</td>");
2963
+				sb.append("<td width=124>" + sp.getName() + "<br1> <font color=999999>Price:</font> <font color=339966>" + getItemNameById(sp.getPriceId()) + "</font> (<font color=LEVEL>" + sp.getPriceCount() + "</font>)</td>");
2964
+				sb.append("<td align=center width=65>" + "<button value=\"Buy\" action=\"bypass -h dressme " + page + " buyskin  " + sp.getId() + " " + type + " " + itemId + "\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" + "</td>");
2965
+				sb.append("<td align=center width=65>" + "<button value=\"Try\" action=\"bypass -h dressme " + page + " tryskin  " + sp.getId() + " " + type + "\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" + "</td>");
2966
+				
2967
+				sb.append("</tr></table>");
2968
+				sb.append("<img src=\"L2UI.Squaregray\" width=\"300\" height=\"1\">");
2969
+				shown++;
2970
+			}
2971
+		}
2972
+		
2973
+		sb.append("<table width=300><tr>");
2974
+		sb.append("<td align=center width=70>" + (page > 1 ? "<button value=\"< PREV\" action=\"bypass -h dressme " + (page - 1) + " skinlist " + type + "\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" : "") + "</td>");
2975
+		sb.append("<td align=center width=140>Page: " + page + "</td>");
2976
+		sb.append("<td align=center width=70>" + (hasMore ? "<button value=\"NEXT >\" action=\"bypass -h dressme " + (page + 1) + " skinlist " + type + "\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" : "") + "</td>");
2977
+		sb.append("</tr></table>");
2978
+		
2979
+		html.replace("%showList%", sb.toString());
2980
+		player.sendPacket(html);
2981
+	}
2982
+	
2983
+	private static void showMySkinList(Player player, int page)
2984
+	{
2985
+		NpcHtmlMessage html = new NpcHtmlMessage(1);
2986
+		html.setFile(player.getLocale(), "html/dressme/myskins.htm");
2987
+		
2988
+		html.replace("%time%", sdf.format(new Date(System.currentTimeMillis())));
2989
+		html.replace("%dat%", (new SimpleDateFormat("dd/MM/yyyy")).format(new Date(System.currentTimeMillis())));
2990
+		
2991
+		final int ITEMS_PER_PAGE = 8;
2992
+		int itemId = 0;
2993
+		
2994
+		int myPage = 1;
2995
+		int i = 0;
2996
+		int shown = 0;
2997
+		boolean hasMore = false;
2998
+		
2999
+		final StringBuilder sb = new StringBuilder();
3000
+		
3001
+		List<SkinPackage> armors = DressMeData.getInstance().getArmorSkinOptions().values().stream().filter(s -> player.hasArmorSkin(s.getId())).collect(Collectors.toList());
3002
+		List<SkinPackage> weapons = DressMeData.getInstance().getWeaponSkinOptions().values().stream().filter(s -> player.hasWeaponSkin(s.getId())).collect(Collectors.toList());
3003
+		List<SkinPackage> hairs = DressMeData.getInstance().getHairSkinOptions().values().stream().filter(s -> player.hasHairSkin(s.getId())).collect(Collectors.toList());
3004
+		List<SkinPackage> faces = DressMeData.getInstance().getFaceSkinOptions().values().stream().filter(s -> player.hasFaceSkin(s.getId())).collect(Collectors.toList());
3005
+		List<SkinPackage> shield = DressMeData.getInstance().getShieldSkinOptions().values().stream().filter(s -> player.hasShieldSkin(s.getId())).collect(Collectors.toList());
3006
+		
3007
+		List<SkinPackage> list = Stream.concat(armors.stream(), weapons.stream()).collect(Collectors.toList());
3008
+		shield.stream().collect(Collectors.toList());
3009
+		List<SkinPackage> list2 = Stream.concat(hairs.stream(), shield.stream()).collect(Collectors.toList());
3010
+		List<SkinPackage> list3 = faces.stream().collect(Collectors.toList());
3011
+		
3012
+		List<SkinPackage> allLists = Stream.concat(list.stream(), Stream.concat(list2.stream(), list3.stream())).collect(Collectors.toList());
3013
+		
3014
+		if (!allLists.isEmpty())
3015
+		{
3016
+			for (SkinPackage sp : allLists)
3017
+			{
3018
+				if (sp == null)
3019
+				{
3020
+					continue;
3021
+				}
3022
+				
3023
+				if (shown == ITEMS_PER_PAGE)
3024
+				{
3025
+					hasMore = true;
3026
+					break;
3027
+				}
3028
+				
3029
+				if (myPage != page)
3030
+				{
3031
+					i++;
3032
+					if (i == ITEMS_PER_PAGE)
3033
+					{
3034
+						myPage++;
3035
+						i = 0;
3036
+					}
3037
+					continue;
3038
+				}
3039
+				
3040
+				if (shown == ITEMS_PER_PAGE)
3041
+				{
3042
+					hasMore = true;
3043
+					break;
3044
+				}
3045
+				
3046
+				switch (sp.getType().toLowerCase())
3047
+				{
3048
+					case "armor":
3049
+						itemId = sp.getChestId();
3050
+						break;
3051
+					case "weapon":
3052
+						itemId = sp.getWeaponId();
3053
+						break;
3054
+					case "hair":
3055
+						itemId = sp.getHairId();
3056
+						break;
3057
+					case "face":
3058
+						itemId = sp.getFaceId();
3059
+						break;
3060
+					case "shield":
3061
+						itemId = sp.getShieldId();
3062
+						break;
3063
+				}
3064
+				
3065
+				sb.append("<table border=0 cellspacing=0 cellpadding=2 height=36><tr>");
3066
+				sb.append("<td width=32 align=center>" + "<button width=32 height=32 back=" + IconTable.getIcon(itemId) + " fore=" + IconTable.getIcon(itemId) + ">" + "</td>");
3067
+				sb.append("<td width=124>" + sp.getName() + "</td>");
3068
+				sb.append("<td align=center width=65>" + "<button value=\"Equip\" action=\"bypass -h dressme " + page + " setskin " + sp.getId() + " " + sp.getType() + " " + itemId + "\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" + "</td>");
3069
+				sb.append("<td align=center width=65>" + "<button value=\"Remove\" action=\"bypass -h dressme " + page + " clean " + sp.getType() + "\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" + "</td>");
3070
+				sb.append("</tr></table>");
3071
+				sb.append("<img src=\"L2UI.Squaregray\" width=\"300\" height=\"1\">");
3072
+				shown++;
3073
+			}
3074
+		}
3075
+		
3076
+		sb.append("<table width=300><tr>");
3077
+		sb.append("<td align=center width=70>" + (page > 1 ? "<button value=\"< PREV\" action=\"bypass -h dressme " + (page - 1) + " myskinlist\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" : "") + "</td>");
3078
+		sb.append("<td align=center width=140>Page: " + page + "</td>");
3079
+		sb.append("<td align=center width=70>" + (hasMore ? "<button value=\"NEXT >\" action=\"bypass -h dressme " + (page + 1) + " myskinlist\" width=65 height=19 back=L2UI_ch3.smallbutton2_over fore=L2UI_ch3.smallbutton2>" : "") + "</td>");
3080
+		sb.append("</tr></table>");
3081
+		
3082
+		html.replace("%showList%", sb.toString());
3083
+		player.sendPacket(html);
3084
+	}
3085
+	
3086
+	public static boolean checkWeapons(Player player, ItemInstance skin, WeaponType weapon1, WeaponType weapon2)
3087
+	{
3088
+		if (player.getActiveWeaponItem().getItemType() == weapon1 && skin.getItem().getItemType() != weapon2)
3089
+		{
3090
+			return false;
3091
+		}
3092
+		
3093
+		return true;
3094
+	}
3095
+	
3096
 }
3097
\ No newline at end of file
3098
diff --git java/net/sf/l2j/gameserver/network/serverpackets/CharInfo.java java/net/sf/l2j/gameserver/network/serverpackets/CharInfo.java
3099
index 8fbcb8c..9a3550b 100644
3100
--- java/net/sf/l2j/gameserver/network/serverpackets/CharInfo.java
3101
+++ java/net/sf/l2j/gameserver/network/serverpackets/CharInfo.java
3102
@@ -10,6 +10,9 @@
3103
 import net.sf.l2j.gameserver.model.actor.Summon;
3104
 import net.sf.l2j.gameserver.model.actor.instance.Cubic;
3105
 
3106
+import Base.Skin.DressMeData;
3107
+import Base.Skin.SkinPackage;
3108
+
3109
 public class CharInfo extends L2GameServerPacket
3110
 {
3111
 	private final Player _player;
3112
@@ -45,16 +48,83 @@
3113
 		
3114
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIRALL));
3115
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.HEAD));
3116
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3117
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3118
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3119
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3120
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3121
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.FEET));
3122
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.CLOAK));
3123
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3124
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3125
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.FACE));
3126
+	       if (Config.ALLOW_DRESS_ME_SYSTEM)
3127
+	       {
3128
+	           if (_player.getWeaponSkinOption() > 0 && getWeaponOption(_player.getWeaponSkinOption()) != null)
3129
+	           {
3130
+	               writeD(getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() : _player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3131
+	           }
3132
+	           else
3133
+	           {
3134
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3135
+	           }
3136
+	           
3137
+	           if (_player.getShieldSkinOption() > 0 && getShieldOption(_player.getShieldSkinOption()) != null)
3138
+	           {
3139
+	               writeD(getShieldOption(_player.getShieldSkinOption()).getShieldId() != 0 ? getShieldOption(_player.getShieldSkinOption()).getShieldId() : _player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3140
+	           }
3141
+	           else
3142
+	           {
3143
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3144
+	           }
3145
+	           
3146
+	           if (_player.getArmorSkinOption() > 0 && getArmorOption(_player.getArmorSkinOption()) != null)
3147
+	           {
3148
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getGlovesId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getGlovesId() : _player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3149
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getChestId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getChestId() : _player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3150
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getLegsId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getLegsId() : _player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3151
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getFeetId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getFeetId() : _player.getInventory().getItemIdFrom(Paperdoll.FEET));
3152
+	           }
3153
+	           else
3154
+	           {
3155
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3156
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3157
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3158
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.FEET));
3159
+	           }
3160
+	           
3161
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.CLOAK));
3162
+	           
3163
+	           if (_player.getWeaponSkinOption() > 0 && getWeaponOption(_player.getWeaponSkinOption()) != null)
3164
+	           {
3165
+	               writeD(getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() : _player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3166
+	           }
3167
+	           else
3168
+	           {
3169
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3170
+	           }
3171
+	           
3172
+	           if (_player.getHairSkinOption() > 0 && getHairOption(_player.getHairSkinOption()) != null)
3173
+	           {
3174
+	               writeD(getHairOption(_player.getHairSkinOption()).getHairId() != 0 ? getHairOption(_player.getHairSkinOption()).getHairId() : _player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3175
+	           }
3176
+	           else
3177
+	           {
3178
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3179
+	           }
3180
+	           
3181
+	           if (_player.getFaceSkinOption() > 0 && getFaceOption(_player.getFaceSkinOption()) != null)
3182
+	           {
3183
+	               writeD(getFaceOption(_player.getFaceSkinOption()).getFaceId() != 0 ? getFaceOption(_player.getFaceSkinOption()).getFaceId() : _player.getInventory().getItemIdFrom(Paperdoll.FACE));
3184
+	           }
3185
+	           else
3186
+	           {
3187
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.FACE));
3188
+	           }
3189
+	           
3190
+	       }
3191
+	       else {
3192
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3193
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3194
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3195
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3196
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3197
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.FEET));
3198
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.CLOAK));
3199
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3200
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3201
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.FACE));
3202
+	       }
3203
 		
3204
 		writeH(0x00);
3205
 		writeH(0x00);
3206
@@ -161,4 +231,30 @@
3207
 		writeD(_player.getAppearance().getTitleColor());
3208
 		writeD(CursedWeaponManager.getInstance().getCurrentStage(_player.getCursedWeaponEquippedId()));
3209
 	}
3210
+	
3211
+	   public SkinPackage getArmorOption(int option)
3212
+	   {
3213
+	      return (DressMeData.getInstance().getArmorSkinsPackage(option));
3214
+	   }
3215
+
3216
+	   public SkinPackage getWeaponOption(int option)
3217
+	   {
3218
+	      return DressMeData.getInstance().getWeaponSkinsPackage(option);
3219
+	   }
3220
+
3221
+	   public SkinPackage getHairOption(int option)
3222
+	   {
3223
+	      return DressMeData.getInstance().getHairSkinsPackage(option);
3224
+	   }
3225
+
3226
+	   public SkinPackage getFaceOption(int option)
3227
+	   {
3228
+	      return DressMeData.getInstance().getFaceSkinsPackage(option);
3229
+	   }
3230
+
3231
+	   public SkinPackage getShieldOption(int option)
3232
+	   {
3233
+	      return DressMeData.getInstance().getShieldSkinsPackage(option);
3234
+	   }	
3235
+	
3236
 }
3237
\ No newline at end of file
3238
diff --git java/net/sf/l2j/gameserver/network/serverpackets/CharSelectInfo.java java/net/sf/l2j/gameserver/network/serverpackets/CharSelectInfo.java
3239
index ce21f4e..9713494 100644
3240
--- java/net/sf/l2j/gameserver/network/serverpackets/CharSelectInfo.java
3241
+++ java/net/sf/l2j/gameserver/network/serverpackets/CharSelectInfo.java
3242
@@ -8,12 +8,16 @@
3243
 
3244
 import net.sf.l2j.commons.pool.ConnectionPool;
3245
 
3246
+import net.sf.l2j.Config;
3247
 import net.sf.l2j.gameserver.data.sql.ClanTable;
3248
 import net.sf.l2j.gameserver.enums.Paperdoll;
3249
 import net.sf.l2j.gameserver.model.CharSelectSlot;
3250
 import net.sf.l2j.gameserver.model.pledge.Clan;
3251
 import net.sf.l2j.gameserver.network.GameClient;
3252
 
3253
+import Base.Skin.DressMeData;
3254
+import Base.Skin.SkinPackage;
3255
+
3256
 public class CharSelectInfo extends L2GameServerPacket
3257
 {
3258
 	private static final String SELECT_INFOS = "SELECT obj_Id, char_name, level, maxHp, curHp, maxMp, curMp, face, hairStyle, hairColor, sex, heading, x, y, z, exp, sp, karma, pvpkills, pkkills, clanid, race, classid, deletetime, title, accesslevel, lastAccess, base_class FROM characters WHERE account_name=?";
3259
@@ -111,16 +115,76 @@
3260
 			writeD(slot.getPaperdollObjectId(Paperdoll.RFINGER));
3261
 			writeD(slot.getPaperdollObjectId(Paperdoll.LFINGER));
3262
 			writeD(slot.getPaperdollObjectId(Paperdoll.HEAD));
3263
-			writeD(slot.getPaperdollObjectId(Paperdoll.RHAND));
3264
-			writeD(slot.getPaperdollObjectId(Paperdoll.LHAND));
3265
-			writeD(slot.getPaperdollObjectId(Paperdoll.GLOVES));
3266
-			writeD(slot.getPaperdollObjectId(Paperdoll.CHEST));
3267
-			writeD(slot.getPaperdollObjectId(Paperdoll.LEGS));
3268
-			writeD(slot.getPaperdollObjectId(Paperdoll.FEET));
3269
-			writeD(slot.getPaperdollObjectId(Paperdoll.CLOAK));
3270
-			writeD(slot.getPaperdollObjectId(Paperdoll.RHAND));
3271
-			writeD(slot.getPaperdollObjectId(Paperdoll.HAIR));
3272
-			writeD(slot.getPaperdollObjectId(Paperdoll.FACE));
3273
+			if (Config.ALLOW_DRESS_ME_SYSTEM)
3274
+			{
3275
+				if (slot.getWeaponSkinOption() > 0 && getWeaponOption(slot.getWeaponSkinOption()) != null)
3276
+				{
3277
+					writeD(getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() : slot.getPaperdollObjectId(Paperdoll.RHAND));
3278
+				}
3279
+				else
3280
+				{
3281
+					writeD(slot.getPaperdollObjectId(Paperdoll.RHAND));
3282
+				}
3283
+				
3284
+				writeD(slot.getPaperdollObjectId(Paperdoll.LHAND));
3285
+				
3286
+				if (slot.getArmorSkinOption() > 0 && getArmorOption(slot.getArmorSkinOption()) != null)
3287
+				{
3288
+					writeD(getArmorOption(slot.getArmorSkinOption()).getGlovesId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getGlovesId() : slot.getPaperdollObjectId(Paperdoll.GLOVES));
3289
+					writeD(getArmorOption(slot.getArmorSkinOption()).getChestId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getChestId() : slot.getPaperdollObjectId(Paperdoll.CHEST));
3290
+					writeD(getArmorOption(slot.getArmorSkinOption()).getLegsId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getLegsId() : slot.getPaperdollObjectId(Paperdoll.LEGS));
3291
+					writeD(getArmorOption(slot.getArmorSkinOption()).getFeetId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getFeetId() : slot.getPaperdollObjectId(Paperdoll.FEET));
3292
+				}
3293
+				else
3294
+				{
3295
+					writeD(slot.getPaperdollObjectId(Paperdoll.GLOVES));
3296
+					writeD(slot.getPaperdollObjectId(Paperdoll.CHEST));
3297
+					writeD(slot.getPaperdollObjectId(Paperdoll.LEGS));
3298
+					writeD(slot.getPaperdollObjectId(Paperdoll.FEET));
3299
+				}
3300
+				
3301
+				writeD(slot.getPaperdollObjectId(Paperdoll.CLOAK));
3302
+				
3303
+				if (slot.getWeaponSkinOption() > 0 && getWeaponOption(slot.getWeaponSkinOption()) != null)
3304
+				{
3305
+					writeD(getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() : slot.getPaperdollObjectId(Paperdoll.RHAND));
3306
+				}
3307
+				else
3308
+				{
3309
+					writeD(slot.getPaperdollObjectId(Paperdoll.RHAND));
3310
+				}
3311
+				
3312
+				if (slot.getHairSkinOption() > 0 && getHairOption(slot.getHairSkinOption()) != null)
3313
+				{
3314
+					writeD(getHairOption(slot.getHairSkinOption()).getHairId() != 0 ? getHairOption(slot.getHairSkinOption()).getHairId() : slot.getPaperdollObjectId(Paperdoll.HAIR));
3315
+				}
3316
+				else
3317
+				{
3318
+					writeD(slot.getPaperdollObjectId(Paperdoll.HAIR));
3319
+				}
3320
+				
3321
+				if (slot.getFaceSkinOption() > 0 && getFaceOption(slot.getFaceSkinOption()) != null)
3322
+				{
3323
+					writeD(getFaceOption(slot.getFaceSkinOption()).getFaceId() != 0 ? getFaceOption(slot.getFaceSkinOption()).getFaceId() : slot.getPaperdollObjectId(Paperdoll.FACE));
3324
+				}
3325
+				else
3326
+				{
3327
+					writeD(slot.getPaperdollObjectId(Paperdoll.FACE));
3328
+				}
3329
+			}
3330
+			else
3331
+			{
3332
+				writeD(slot.getPaperdollObjectId(Paperdoll.RHAND));
3333
+				writeD(slot.getPaperdollObjectId(Paperdoll.LHAND));
3334
+				writeD(slot.getPaperdollObjectId(Paperdoll.GLOVES));
3335
+				writeD(slot.getPaperdollObjectId(Paperdoll.CHEST));
3336
+				writeD(slot.getPaperdollObjectId(Paperdoll.LEGS));
3337
+				writeD(slot.getPaperdollObjectId(Paperdoll.FEET));
3338
+				writeD(slot.getPaperdollObjectId(Paperdoll.CLOAK));
3339
+				writeD(slot.getPaperdollObjectId(Paperdoll.RHAND));
3340
+				writeD(slot.getPaperdollObjectId(Paperdoll.HAIR));
3341
+				writeD(slot.getPaperdollObjectId(Paperdoll.FACE));
3342
+			}
3343
 			
3344
 			writeD(slot.getPaperdollItemId(Paperdoll.HAIRALL));
3345
 			writeD(slot.getPaperdollItemId(Paperdoll.REAR));
3346
@@ -129,16 +193,76 @@
3347
 			writeD(slot.getPaperdollItemId(Paperdoll.RFINGER));
3348
 			writeD(slot.getPaperdollItemId(Paperdoll.LFINGER));
3349
 			writeD(slot.getPaperdollItemId(Paperdoll.HEAD));
3350
-			writeD(slot.getPaperdollItemId(Paperdoll.RHAND));
3351
-			writeD(slot.getPaperdollItemId(Paperdoll.LHAND));
3352
-			writeD(slot.getPaperdollItemId(Paperdoll.GLOVES));
3353
-			writeD(slot.getPaperdollItemId(Paperdoll.CHEST));
3354
-			writeD(slot.getPaperdollItemId(Paperdoll.LEGS));
3355
-			writeD(slot.getPaperdollItemId(Paperdoll.FEET));
3356
-			writeD(slot.getPaperdollItemId(Paperdoll.CLOAK));
3357
-			writeD(slot.getPaperdollItemId(Paperdoll.RHAND));
3358
-			writeD(slot.getPaperdollItemId(Paperdoll.HAIR));
3359
-			writeD(slot.getPaperdollItemId(Paperdoll.FACE));
3360
+			if (Config.ALLOW_DRESS_ME_SYSTEM)
3361
+			{
3362
+				if (slot.getWeaponSkinOption() > 0 && getWeaponOption(slot.getWeaponSkinOption()) != null)
3363
+				{
3364
+					writeD(getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() : slot.getPaperdollItemId(Paperdoll.RHAND));
3365
+				}
3366
+				else
3367
+				{
3368
+					writeD(slot.getPaperdollItemId(Paperdoll.RHAND));
3369
+				}
3370
+				
3371
+				writeD(slot.getPaperdollItemId(Paperdoll.LHAND));
3372
+				
3373
+				if (slot.getArmorSkinOption() > 0 && getArmorOption(slot.getArmorSkinOption()) != null)
3374
+				{
3375
+					writeD(getArmorOption(slot.getArmorSkinOption()).getGlovesId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getGlovesId() : slot.getPaperdollItemId(Paperdoll.GLOVES));
3376
+					writeD(getArmorOption(slot.getArmorSkinOption()).getChestId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getChestId() : slot.getPaperdollItemId(Paperdoll.CHEST));
3377
+					writeD(getArmorOption(slot.getArmorSkinOption()).getLegsId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getLegsId() : slot.getPaperdollItemId(Paperdoll.LEGS));
3378
+					writeD(getArmorOption(slot.getArmorSkinOption()).getFeetId() != 0 ? getArmorOption(slot.getArmorSkinOption()).getFeetId() : slot.getPaperdollItemId(Paperdoll.FEET));
3379
+				}
3380
+				else
3381
+				{
3382
+					writeD(slot.getPaperdollItemId(Paperdoll.GLOVES));
3383
+					writeD(slot.getPaperdollItemId(Paperdoll.CHEST));
3384
+					writeD(slot.getPaperdollItemId(Paperdoll.LEGS));
3385
+					writeD(slot.getPaperdollItemId(Paperdoll.FEET));
3386
+				}
3387
+				
3388
+				writeD(slot.getPaperdollItemId(Paperdoll.CLOAK));
3389
+				
3390
+				if (slot.getWeaponSkinOption() > 0 && getWeaponOption(slot.getWeaponSkinOption()) != null)
3391
+				{
3392
+					writeD(getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(slot.getWeaponSkinOption()).getWeaponId() : slot.getPaperdollItemId(Paperdoll.RHAND));
3393
+				}
3394
+				else
3395
+				{
3396
+					writeD(slot.getPaperdollItemId(Paperdoll.RHAND));
3397
+				}
3398
+				
3399
+				if (slot.getHairSkinOption() > 0 && getHairOption(slot.getHairSkinOption()) != null)
3400
+				{
3401
+					writeD(getHairOption(slot.getHairSkinOption()).getHairId() != 0 ? getHairOption(slot.getHairSkinOption()).getHairId() : slot.getPaperdollItemId(Paperdoll.HAIR));
3402
+				}
3403
+				else
3404
+				{
3405
+					writeD(slot.getPaperdollItemId(Paperdoll.HAIR));
3406
+				}
3407
+				
3408
+				if (slot.getFaceSkinOption() > 0 && getFaceOption(slot.getFaceSkinOption()) != null)
3409
+				{
3410
+					writeD(getFaceOption(slot.getFaceSkinOption()).getFaceId() != 0 ? getFaceOption(slot.getFaceSkinOption()).getFaceId() : slot.getPaperdollItemId(Paperdoll.FACE));
3411
+				}
3412
+				else
3413
+				{
3414
+					writeD(slot.getPaperdollItemId(Paperdoll.FACE));
3415
+				}
3416
+			}
3417
+			else
3418
+			{
3419
+				writeD(slot.getPaperdollItemId(Paperdoll.RHAND));
3420
+				writeD(slot.getPaperdollItemId(Paperdoll.LHAND));
3421
+				writeD(slot.getPaperdollItemId(Paperdoll.GLOVES));
3422
+				writeD(slot.getPaperdollItemId(Paperdoll.CHEST));
3423
+				writeD(slot.getPaperdollItemId(Paperdoll.LEGS));
3424
+				writeD(slot.getPaperdollItemId(Paperdoll.FEET));
3425
+				writeD(slot.getPaperdollItemId(Paperdoll.CLOAK));
3426
+				writeD(slot.getPaperdollItemId(Paperdoll.RHAND));
3427
+				writeD(slot.getPaperdollItemId(Paperdoll.HAIR));
3428
+				writeD(slot.getPaperdollItemId(Paperdoll.FACE));
3429
+			}
3430
 			
3431
 			writeD(slot.getHairStyle());
3432
 			writeD(slot.getHairColor());
3433
@@ -235,6 +359,7 @@
3434
 					}
3435
 					
3436
 					slot.setClassId(activeClassId);
3437
+					loadCharacterDressMeInfo(slot, objectId);
3438
 					
3439
 					// Get the augmentation for equipped weapon.
3440
 					final int weaponObjId = slot.getPaperdollObjectId(Paperdoll.RHAND);
3441
@@ -273,4 +398,49 @@
3442
 		
3443
 		return new CharSelectSlot[0];
3444
 	}
3445
+	
3446
+	private static void loadCharacterDressMeInfo(final CharSelectSlot charInfopackage, final int objectId)
3447
+	{
3448
+		try (Connection con = ConnectionPool.getConnection();
3449
+			PreparedStatement statement = con.prepareStatement("SELECT obj_Id, armor_skins, armor_skin_option, weapon_skins, weapon_skin_option, hair_skins, hair_skin_option, face_skins, face_skin_option FROM characters_dressme_data WHERE obj_id=?"))
3450
+		{
3451
+			
3452
+			statement.setInt(1, objectId);
3453
+			try (ResultSet chardata = statement.executeQuery())
3454
+			{
3455
+				if (chardata.next())
3456
+				{
3457
+					charInfopackage.setArmorSkinOption(chardata.getInt("armor_skin_option"));
3458
+					charInfopackage.setWeaponSkinOption(chardata.getInt("weapon_skin_option"));
3459
+					charInfopackage.setHairSkinOption(chardata.getInt("hair_skin_option"));
3460
+					charInfopackage.setFaceSkinOption(chardata.getInt("face_skin_option"));
3461
+				}
3462
+			}
3463
+		}
3464
+		catch (final Exception e)
3465
+		{
3466
+			e.printStackTrace();
3467
+		}
3468
+	}
3469
+	
3470
+	public SkinPackage getArmorOption(int option)
3471
+	{
3472
+		return (DressMeData.getInstance().getArmorSkinsPackage(option));
3473
+	}
3474
+	
3475
+	public SkinPackage getWeaponOption(int option)
3476
+	{
3477
+		return DressMeData.getInstance().getWeaponSkinsPackage(option);
3478
+	}
3479
+	
3480
+	public SkinPackage getHairOption(int option)
3481
+	{
3482
+		return DressMeData.getInstance().getHairSkinsPackage(option);
3483
+	}
3484
+	
3485
+	public SkinPackage getFaceOption(int option)
3486
+	{
3487
+		return DressMeData.getInstance().getFaceSkinsPackage(option);
3488
+	}
3489
+	
3490
 }
3491
\ No newline at end of file
3492
diff --git java/net/sf/l2j/gameserver/network/serverpackets/UserInfo.java java/net/sf/l2j/gameserver/network/serverpackets/UserInfo.java
3493
index 4468bde..636be18 100644
3494
--- java/net/sf/l2j/gameserver/network/serverpackets/UserInfo.java
3495
+++ java/net/sf/l2j/gameserver/network/serverpackets/UserInfo.java
3496
@@ -9,6 +9,9 @@
3497
 import net.sf.l2j.gameserver.model.actor.Summon;
3498
 import net.sf.l2j.gameserver.model.actor.instance.Cubic;
3499
 
3500
+import Base.Skin.DressMeData;
3501
+import Base.Skin.SkinPackage;
3502
+
3503
 public class UserInfo extends L2GameServerPacket
3504
 {
3505
 	private final Player _player;
3506
@@ -61,16 +64,83 @@
3507
 		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RFINGER));
3508
 		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LFINGER));
3509
 		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.HEAD));
3510
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3511
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LHAND));
3512
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.GLOVES));
3513
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.CHEST));
3514
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LEGS));
3515
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.FEET));
3516
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.CLOAK));
3517
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3518
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.HAIR));
3519
-		writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.FACE));
3520
+	      if (Config.ALLOW_DRESS_ME_SYSTEM)
3521
+	      {
3522
+	          if (_player.getWeaponSkinOption() > 0 && getWeaponOption(_player.getWeaponSkinOption()) != null)
3523
+	          {
3524
+	              writeD(getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3525
+	          }
3526
+	          else
3527
+	          {
3528
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3529
+	          }
3530
+	          
3531
+	          if (_player.getShieldSkinOption() > 0 && getShieldOption(_player.getShieldSkinOption()) != null)
3532
+	          {
3533
+	              writeD(getShieldOption(_player.getShieldSkinOption()).getShieldId() != 0 ? getShieldOption(_player.getShieldSkinOption()).getShieldId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.LHAND));
3534
+	          }
3535
+	          else
3536
+	          {
3537
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LHAND));
3538
+	          }
3539
+	          
3540
+	          if (_player.getArmorSkinOption() > 0 && getArmorOption(_player.getArmorSkinOption()) != null)
3541
+	          {
3542
+	              writeD(getArmorOption(_player.getArmorSkinOption()).getGlovesId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getGlovesId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.GLOVES));
3543
+	              writeD(getArmorOption(_player.getArmorSkinOption()).getChestId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getChestId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.CHEST));
3544
+	              writeD(getArmorOption(_player.getArmorSkinOption()).getLegsId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getLegsId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.LEGS));
3545
+	              writeD(getArmorOption(_player.getArmorSkinOption()).getFeetId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getFeetId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.FEET));
3546
+	          }
3547
+	          else
3548
+	          {
3549
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.GLOVES));
3550
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.CHEST));
3551
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LEGS));
3552
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.FEET));
3553
+	          }
3554
+	          
3555
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.CLOAK));
3556
+	          
3557
+	          if (_player.getWeaponSkinOption() > 0 && getWeaponOption(_player.getWeaponSkinOption()) != null)
3558
+	          {
3559
+	              writeD(getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3560
+	          }
3561
+	          else
3562
+	          {
3563
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3564
+	          }
3565
+	          
3566
+	          if (_player.getHairSkinOption() > 0 && getHairOption(_player.getHairSkinOption()) != null)
3567
+	          {
3568
+	              writeD(getHairOption(_player.getHairSkinOption()).getHairId() != 0 ? getHairOption(_player.getHairSkinOption()).getHairId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.HAIR));
3569
+	          }
3570
+	          else
3571
+	          {
3572
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.HAIR));
3573
+	          }
3574
+	          
3575
+	          if (_player.getFaceSkinOption() > 0 && getFaceOption(_player.getFaceSkinOption()) != null)
3576
+	          {
3577
+	              writeD(getFaceOption(_player.getFaceSkinOption()).getFaceId() != 0 ? getFaceOption(_player.getFaceSkinOption()).getFaceId() : _player.getInventory().getItemObjectIdFrom(Paperdoll.FACE));
3578
+	          }
3579
+	          else
3580
+	          {
3581
+	              writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.FACE));
3582
+	          }
3583
+	          
3584
+	      }
3585
+	      else {
3586
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3587
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LHAND));
3588
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.GLOVES));
3589
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.CHEST));
3590
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.LEGS));
3591
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.FEET));
3592
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.CLOAK));
3593
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.RHAND));
3594
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.HAIR));
3595
+	          writeD(_player.getInventory().getItemObjectIdFrom(Paperdoll.FACE));
3596
+	      }
3597
 		
3598
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIRALL));
3599
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.REAR));
3600
@@ -79,16 +149,83 @@
3601
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.RFINGER));
3602
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.LFINGER));
3603
 		writeD(_player.getInventory().getItemIdFrom(Paperdoll.HEAD));
3604
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3605
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3606
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3607
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3608
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3609
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.FEET));
3610
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.CLOAK));
3611
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3612
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3613
-		writeD(_player.getInventory().getItemIdFrom(Paperdoll.FACE));
3614
+	       if (Config.ALLOW_DRESS_ME_SYSTEM)
3615
+	       {
3616
+	           if (_player.getWeaponSkinOption() > 0 && getWeaponOption(_player.getWeaponSkinOption()) != null)
3617
+	           {
3618
+	               writeD(getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() : _player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3619
+	           }
3620
+	           else
3621
+	           {
3622
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3623
+	           }
3624
+	           
3625
+	           if (_player.getShieldSkinOption() > 0 && getShieldOption(_player.getShieldSkinOption()) != null)
3626
+	           {
3627
+	               writeD(getShieldOption(_player.getShieldSkinOption()).getShieldId() != 0 ? getShieldOption(_player.getShieldSkinOption()).getShieldId() : _player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3628
+	           }
3629
+	           else
3630
+	           {
3631
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3632
+	           }
3633
+	           
3634
+	           if (_player.getArmorSkinOption() > 0 && getArmorOption(_player.getArmorSkinOption()) != null)
3635
+	           {
3636
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getGlovesId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getGlovesId() : _player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3637
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getChestId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getChestId() : _player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3638
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getLegsId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getLegsId() : _player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3639
+	               writeD(getArmorOption(_player.getArmorSkinOption()).getFeetId() != 0 ? getArmorOption(_player.getArmorSkinOption()).getFeetId() : _player.getInventory().getItemIdFrom(Paperdoll.FEET));
3640
+	           }
3641
+	           else
3642
+	           {
3643
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3644
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3645
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3646
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.FEET));
3647
+	           }
3648
+	           
3649
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.CLOAK));
3650
+	           
3651
+	           if (_player.getWeaponSkinOption() > 0 && getWeaponOption(_player.getWeaponSkinOption()) != null)
3652
+	           {
3653
+	               writeD(getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() != 0 ? getWeaponOption(_player.getWeaponSkinOption()).getWeaponId() : _player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3654
+	           }
3655
+	           else
3656
+	           {
3657
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3658
+	           }
3659
+	           
3660
+	           if (_player.getHairSkinOption() > 0 && getHairOption(_player.getHairSkinOption()) != null)
3661
+	           {
3662
+	               writeD(getHairOption(_player.getHairSkinOption()).getHairId() != 0 ? getHairOption(_player.getHairSkinOption()).getHairId() : _player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3663
+	           }
3664
+	           else
3665
+	           {
3666
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3667
+	           }
3668
+	           
3669
+	           if (_player.getFaceSkinOption() > 0 && getFaceOption(_player.getFaceSkinOption()) != null)
3670
+	           {
3671
+	               writeD(getFaceOption(_player.getFaceSkinOption()).getFaceId() != 0 ? getFaceOption(_player.getFaceSkinOption()).getFaceId() : _player.getInventory().getItemIdFrom(Paperdoll.FACE));
3672
+	           }
3673
+	           else
3674
+	           {
3675
+	               writeD(_player.getInventory().getItemIdFrom(Paperdoll.FACE));
3676
+	           }
3677
+	           
3678
+	       }
3679
+	       else {
3680
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3681
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.LHAND));
3682
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.GLOVES));
3683
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.CHEST));
3684
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.LEGS));
3685
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.FEET));
3686
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.CLOAK));
3687
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.RHAND));
3688
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.HAIR));
3689
+	           writeD(_player.getInventory().getItemIdFrom(Paperdoll.FACE));
3690
+	       }
3691
 		
3692
 		writeH(0x00);
3693
 		writeH(0x00);
3694
@@ -212,4 +349,28 @@
3695
 		writeD(_player.getAppearance().getTitleColor());
3696
 		writeD(CursedWeaponManager.getInstance().getCurrentStage(_player.getCursedWeaponEquippedId()));
3697
 	}
3698
+    public SkinPackage getArmorOption(int option)
3699
+    {
3700
+        return (DressMeData.getInstance().getArmorSkinsPackage(option));
3701
+    }
3702
+    
3703
+    public SkinPackage getWeaponOption(int option)
3704
+    {
3705
+        return DressMeData.getInstance().getWeaponSkinsPackage(option);
3706
+    }
3707
+    
3708
+    public SkinPackage getHairOption(int option)
3709
+    {
3710
+        return DressMeData.getInstance().getHairSkinsPackage(option);
3711
+    }
3712
+    
3713
+    public SkinPackage getFaceOption(int option)
3714
+    {
3715
+        return DressMeData.getInstance().getFaceSkinsPackage(option);
3716
+    }
3717
+    
3718
+    public SkinPackage getShieldOption(int option)
3719
+    {
3720
+        return DressMeData.getInstance().getShieldSkinsPackage(option);
3721
+    }
3722
 }
3723
\ No newline at end of file
3724
diff --git server/gameserver/data/html/dressme/allskins.htm server/gameserver/data/html/dressme/allskins.htm
3725
new file mode 100644
3726
index 0000000..c865d6a
3727
--- /dev/null
3728
+++ server/gameserver/data/html/dressme/allskins.htm
3729
@@ -0,0 +1,20 @@
3730
+<html>
3731
+<body>
3732
+<img src="L2UI.Squaregray" width="300" height="1">
3733
+<table width=300 border=0 cellspacing=0 cellpadding=1 bgcolor=000000 height=15>
3734
+<tr>
3735
+<td width=36 align=center></td>
3736
+<td width=120 align=left>Name</td>
3737
+<td width=65 align=left>Actions</td>
3738
+</tr>
3739
+</table>
3740
+<img src="L2UI.Squaregray" width="300" height="1">
3741
+
3742
+%showList%
3743
+
3744
+<center>
3745
+<button value="Back" action="bypass -h custom_dressme_back" width=65 height=19 back="L2UI_ch3.smallbutton2_over" fore="L2UI_ch3.smallbutton2">
3746
+</center>
3747
+
3748
+</body>
3749
+</html>
3750
\ No newline at end of file
3751
diff --git server/gameserver/data/html/dressme/index.htm server/gameserver/data/html/dressme/index.htm
3752
new file mode 100644
3753
index 0000000..f03dd39
3754
--- /dev/null
3755
+++ server/gameserver/data/html/dressme/index.htm
3756
@@ -0,0 +1,26 @@
3757
+<html>
3758
+<title>Skins Shop</title>
3759
+<body>
3760
+<br>
3761
+<center>Skins:</center>
3762
+
3763
+<table width=300>
3764
+<tr>
3765
+<td align=center><button value="Armor buy/try" action="bypass -h dressme 1 skinlist armor" width=134 height=19 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3"></td>
3766
+</tr>
3767
+<tr>
3768
+<td align=center><button value="Weapon buy/try" action="bypass -h dressme 1 skinlist weapon" width=134 height=19 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3"></td>
3769
+</tr>
3770
+<tr>
3771
+<td align=center><button value="Hair buy/try" action="bypass -h dressme 1 skinlist hair" width=134 height=19 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3"></td>
3772
+</tr>
3773
+<tr>
3774
+<td align=center><button value="Face buy/try" action="bypass -h dressme 1 skinlist face" width=134 height=19 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3"></td>
3775
+</tr>
3776
+<tr>
3777
+<td align=center><button value="Shield buy/try" action="bypass -h dressme 1 skinlist shield" width=134 height=19 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3"></td>
3778
+</tr>
3779
+<tr>
3780
+<td align=center><button value="My skins" action="bypass -h dressme 1 myskinlist" width=134 height=19 back="L2UI_ch3.BigButton3_over" fore="L2UI_ch3.BigButton3"></td>
3781
+</tr>
3782
+</table>
3783
diff --git server/gameserver/data/html/dressme/myskins.htm server/gameserver/data/html/dressme/myskins.htm
3784
new file mode 100644
3785
index 0000000..2547f1e
3786
--- /dev/null
3787
+++ server/gameserver/data/html/dressme/myskins.htm
3788
@@ -0,0 +1,21 @@
3789
+<html>
3790
+<body>
3791
+<img src="L2UI.Squaregray" width="300" height="1">
3792
+<table border=0 cellspacing=0 cellpadding=2 bgcolor=000000 height=20>
3793
+<tr>
3794
+<td width=32 align=center></td>
3795
+<td width=203 align=left>Name</td>
3796
+<td width=65 align=left>Actions</td>
3797
+</tr>
3798
+</table>
3799
+<img src="L2UI.Squaregray" width="300" height="1">
3800
+
3801
+%showList%
3802
+
3803
+<br>
3804
+<br>
3805
+<center>
3806
+<button value="Back" action="bypass -h custom_dressme_back" width=65 height=19 back="L2UI_ch3.Btn1_normalOn" fore="L2UI_ch3.Btn1_normal">
3807
+</center>
3808
+</body>
3809
+</html>
3810
\ No newline at end of file
3811
diff --git server/gameserver/data/xml/dressme.xml server/gameserver/data/xml/dressme.xml
3812
new file mode 100644
3813
index 0000000..cd823a3
3814
--- /dev/null
3815
+++ server/gameserver/data/xml/dressme.xml
3816
@@ -0,0 +1,22 @@
3817
+<?xml version="1.0" encoding="UTF-8"?>
3818
+<list>
3819
+	<skin type="armor"> <!-- Armors -->
3820
+		<type id="1" name="Draconic Armor" chestId="6379" legsId="0" glovesId="6380" feetId="6381" priceId="57" priceCount="100"/>
3821
+		<type id="2" name="Blue Wolf Leather Armor" chestId="2391" legsId="0" glovesId="0" feetId="0" priceId="57" priceCount="100"/>
3822
+	</skin>
3823
+	<skin type="weapon"> <!-- Weapons -->
3824
+		<type id="1" name="Draconic Bow" weaponId="7575" priceId="57" priceCount="100"/>
3825
+		<type id="2" name="Arcana Mace" weaponId="6608"  priceId="57" priceCount="100"/>
3826
+		<type id="3" name="Keshanberk*Keshanberk" weaponId="5704" priceId="57" priceCount="100"/>
3827
+	</skin>
3828
+	<skin type="hair"> <!-- Hairs -->
3829
+		<type id="1" name="Cat Ear" hairId="6843" priceId="57" priceCount="100"/>
3830
+	</skin>
3831
+	<skin type="face"> <!-- Faces -->
3832
+		<type id="1" name="Party Mask" faceId="5808" priceId="57" priceCount="100"/>
3833
+	</skin>
3834
+	<skin type="shield"> <!-- Shields -->
3835
+		<type id="1" name="Shield of Night" shieldId="2498" priceId="57" priceCount="100"/>
3836
+		<type id="2" name="Imperial Shield" shieldId="6377" priceId="57" priceCount="100"/>
3837
+	</skin>
3838
+</list>
3839
\ No newline at end of file
3840