Skip to content

Commit 0722296

Browse files
authored
Merge pull request #7 from Gml-Launcher/develop
Update to v1.0.3
2 parents 7713028 + 6fd551d commit 0722296

File tree

12 files changed

+152
-50
lines changed

12 files changed

+152
-50
lines changed

Gml.Web.Skin.Service.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{3E651A
1212
Dockerfile = Dockerfile
1313
.dockerignore = .dockerignore
1414
.gitignore = .gitignore
15+
compose.yaml = compose.yaml
1516
EndProjectSection
1617
EndProject
1718
Global

compose.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
services:
2+
gml.web.skin.service:
3+
image: gml.web.skin.service
4+
container_name: gml-web-skins
5+
build:
6+
context: src/Gml.Web.Skin.Service
7+
dockerfile: Dockerfile
8+
ports:
9+
- 5000:8085
10+
restart: always
11+
environment:
12+
- ASPNETCORE_ENVIRONMENT=Development
13+
- ASPNETCORE_URLS=http://+:8085;
14+
user: "${UID}:${GID}"
15+
volumes:
16+
- ./data/TextureService:/app/Storage
1.75 KB
Loading

src/Gml.Web.Skin.Service/Core/Extensions/Application/ApplicationExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ private static WebApplication AddRoutes(this WebApplication app)
5858
app.MapGet("/{userName}", TextureRequests.GetUserTexture);
5959

6060
app.MapPost("/skin/{userName}", TextureRequests.LoadSkin).DisableAntiforgery();
61+
app.MapDelete("/skin/{userName}", TextureRequests.DeleteSkin);
6162
app.MapGet("/skin/{userName}/{uuid?}", TextureRequests.GetSkin);
6263
app.MapGet("/skin/{userName}/head/{size}", TextureRequests.GetSkinHead);
6364
app.MapGet("/skin/{userName}/front/{size}", TextureRequests.GetSkinFront);
@@ -66,6 +67,7 @@ private static WebApplication AddRoutes(this WebApplication app)
6667

6768
app.MapGet("/cloak/{userName}", TextureRequests.GetCloakTexture);
6869
app.MapPost("/cloak/{userName}", TextureRequests.LoadCloak).DisableAntiforgery();;
70+
app.MapDelete("/cloak/{userName}", TextureRequests.DeleteCloak);
6971
app.MapGet("/cloak/{userName}/front/{size}", TextureRequests.GetCloak);
7072

7173
app.MapGet("/refresh/{userName}", TextureRequests.RefreshCache);

src/Gml.Web.Skin.Service/Core/Requests/TextureRequests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ internal static async Task<IResult> LoadSkin(HttpRequest request, [FromForm] IFo
2323

2424
return Results.Ok(mapper.Map<UserTextureReadDto>(texture));
2525
}
26+
internal static async Task<IResult> DeleteSkin(HttpRequest request, IMapper mapper,
27+
string userName)
28+
{
29+
30+
var filePath = Path.Combine(SkinHelper.SkinTextureDirectory, $"{userName}.png");
31+
32+
if (!File.Exists(filePath))
33+
return Results.NotFound();
34+
35+
File.Delete(filePath);
36+
return Results.Ok();
37+
38+
}
2639

2740
internal static async Task<IResult> LoadCloak(HttpRequest request, [FromForm] IFormFile file, IMapper mapper,
2841
string userName)
@@ -41,6 +54,18 @@ internal static async Task<IResult> LoadCloak(HttpRequest request, [FromForm] IF
4154
return Results.Ok(mapper.Map<UserTextureReadDto>(texture));
4255
}
4356

57+
internal static async Task<IResult> DeleteCloak(HttpRequest request, IMapper mapper,
58+
string userName)
59+
{
60+
var filePath = Path.Combine(SkinHelper.CloakTextureDirectory, $"{userName}.png");
61+
62+
if (!File.Exists(filePath))
63+
return Results.NotFound();
64+
65+
File.Delete(filePath);
66+
return Results.Ok();
67+
}
68+
4469
internal static Task<IResult> GetSkin(HttpRequest request, string userName, string? uuid)
4570
{
4671
var user = SkinHelper.Create($"http://{request.Host.Value}", userName.Substring(2, userName.Length - 2));

src/Gml.Web.Skin.Service/Core/SkinViewer/SkinViewer.cs

Lines changed: 81 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ public abstract class SkinViewer
88
{
99
public static byte[] GetHead(string skinPath, UserTexture userTexture, int size)
1010
{
11+
if (!File.Exists(skinPath))
12+
{
13+
return [];
14+
}
15+
1116
using var inputImage = Image.Load(skinPath);
1217

1318
var scaleFactor = inputImage.Width / 64;
@@ -44,104 +49,124 @@ public static byte[] GetFront(string skinPath, UserTexture user, int size)
4449
using var inputImage = Image.Load(skinPath);
4550

4651
var scaleFactor = inputImage.Width / 64;
52+
var extendedSkin = inputImage.Height / scaleFactor >= 64;
4753

4854
var croppedHead = inputImage.Clone(ctx =>
4955
ctx.Crop(new Rectangle(8 * scaleFactor, 8 * scaleFactor, 8 * scaleFactor, 8 * scaleFactor)));
50-
5156
var croppedBody = inputImage.Clone(ctx =>
5257
ctx.Crop(new Rectangle(20 * scaleFactor, 20 * scaleFactor, 8 * scaleFactor, 12 * scaleFactor)));
53-
54-
var croppedLeg = inputImage.Clone(ctx =>
58+
var leftCroppedLeg = inputImage.Clone(ctx =>
5559
ctx.Crop(new Rectangle(4 * scaleFactor, 20 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)));
56-
57-
var croppedArm = inputImage.Clone(ctx =>
60+
var leftCroppedArm = inputImage.Clone(ctx =>
5861
ctx.Crop(new Rectangle(44 * scaleFactor, 20 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)));
59-
60-
var newWidth = croppedArm.Width * 2 + croppedBody.Width;
61-
var newHeight = croppedHead.Height + croppedBody.Height + croppedArm.Height;
62+
63+
var rightCroppedLeg = extendedSkin
64+
? inputImage.Clone(ctx =>
65+
ctx.Crop(new Rectangle(20 * scaleFactor, 52 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)))
66+
: leftCroppedLeg.Clone(x => x.Flip(FlipMode.Horizontal));
67+
68+
var rightCroppedArm = extendedSkin
69+
? inputImage.Clone(ctx =>
70+
ctx.Crop(new Rectangle(36 * scaleFactor, 52 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)))
71+
: leftCroppedArm.Clone(x => x.Flip(FlipMode.Horizontal));
72+
73+
var secondLayerHead = inputImage.Clone(ctx =>
74+
ctx.Crop(new Rectangle(40 * scaleFactor, 8 * scaleFactor, 8 * scaleFactor, 8 * scaleFactor)));
75+
76+
// var secondLayerArm = inputImage.Clone(ctx =>
77+
// ctx.Crop(new Rectangle(44 * scaleFactor, 52 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)));
78+
79+
var newWidth = leftCroppedArm.Width * 2 + croppedBody.Width;
80+
var newHeight = croppedHead.Height + croppedBody.Height + leftCroppedArm.Height;
6281

6382
var combinedImage = new Image<Rgba32>(newWidth, newHeight);
6483

6584
combinedImage.Mutate(context =>
6685
{
67-
var headPosition = new Rectangle(croppedArm.Width, 0, croppedHead.Width, croppedHead.Height);
86+
var headPosition = new Rectangle(leftCroppedArm.Width, 0, croppedHead.Width, croppedHead.Height);
6887
var bodyPosition = new Rectangle(headPosition.X, croppedHead.Height, croppedBody.Width, croppedBody.Height);
6988

70-
var leftArmPosition = new Rectangle(0, bodyPosition.Y, croppedArm.Width, croppedArm.Height);
89+
var leftArmPosition = new Rectangle(0, bodyPosition.Y, leftCroppedArm.Width, leftCroppedArm.Height);
7190
var rightArmPosition = new Rectangle(leftArmPosition.Width + bodyPosition.Width, leftArmPosition.Y,
7291
leftArmPosition.Width, leftArmPosition.Height);
7392

7493
var leftLegPosition = new Rectangle(leftArmPosition.Width, headPosition.Height + bodyPosition.Height,
75-
croppedLeg.Width, croppedLeg.Height);
94+
leftCroppedLeg.Width, leftCroppedLeg.Height);
7695
var rightLegPosition = new Rectangle(leftArmPosition.Width + leftLegPosition.Width,
7796
headPosition.Height + bodyPosition.Height, leftLegPosition.Width, leftLegPosition.Height);
7897

7998
context.DrawImage(croppedHead, new Point(headPosition.X, headPosition.Y), 1f);
8099
context.DrawImage(croppedBody, new Point(bodyPosition.X, bodyPosition.Y), 1f);
81-
context.DrawImage(croppedArm, new Point(leftArmPosition.X, leftArmPosition.Y), 1f);
82-
context.DrawImage(croppedArm, new Point(rightArmPosition.X, rightArmPosition.Y), 1f);
83-
context.DrawImage(croppedLeg, new Point(leftLegPosition.X, leftLegPosition.Y), 1f);
84-
context.DrawImage(croppedLeg, new Point(rightLegPosition.X, rightLegPosition.Y), 1f);
100+
context.DrawImage(leftCroppedArm, new Point(leftArmPosition.X, leftArmPosition.Y), 1f);
101+
context.DrawImage(rightCroppedArm, new Point(rightArmPosition.X, rightArmPosition.Y), 1f);
102+
context.DrawImage(leftCroppedLeg, new Point(leftLegPosition.X, leftLegPosition.Y), 1f);
103+
context.DrawImage(rightCroppedLeg, new Point(rightLegPosition.X, rightLegPosition.Y), 1f);
85104

86-
// context.DrawImage(croppedArm, new Point(0, 8 * scaleFactor), 1f);
87-
// context.DrawImage(croppedLeg, new Point(200, 200), 1f);
105+
context.DrawImage(secondLayerHead, new Point(headPosition.X, headPosition.Y), 1f);
88106
});
89107

90-
using var memoryStream = new MemoryStream();
91-
if (inputImage.Metadata.DecodedImageFormat != null)
92-
combinedImage.Save(memoryStream, inputImage.Metadata.DecodedImageFormat);
93-
else
94-
combinedImage.Save(memoryStream, new PngEncoder());
95-
96-
// var image = ResizeImage(size, inputImage, combinedImage);
97-
98108
if (size != combinedImage.Width)
99109
{
100110
var scaleSize = GetScaleSize(size, combinedImage.Width);
101-
102111
if (scaleSize != 0)
103112
combinedImage = combinedImage.Clone(ctx => ctx.Resize(combinedImage.Width * scaleSize,
104113
combinedImage.Height * scaleSize, KnownResamplers.Box));
105114
}
106115

107-
using var resizeMemoryStream = new MemoryStream();
108-
109-
if (inputImage.Metadata.DecodedImageFormat != null)
110-
combinedImage.Save(resizeMemoryStream, inputImage.Metadata.DecodedImageFormat);
111-
else
112-
combinedImage.Save(resizeMemoryStream, new PngEncoder());
113-
114-
return resizeMemoryStream.ToArray();
116+
using var memoryStream = new MemoryStream();
117+
combinedImage.Save(memoryStream, new PngEncoder());
118+
return memoryStream.ToArray();
115119
}
116120

117121
public static byte[] GetBack(UserTexture user, int size, bool includeCloak = false)
118122
{
119123
using var inputImage = Image.Load(user.SkinFullPath);
120124
using var cloakImage = includeCloak && user.HasCloak ? Image.Load(user.CloakFullPath) : null;
121125

122-
var scaleFactor = inputImage.Width / 64;
123-
126+
var skinScaleFactor = inputImage.Width / 64;
127+
var cloakScaleFactor = cloakImage?.Width >= 64 ? cloakImage.Width / 64 : 1;
128+
var needSkinResizeToCloakSize = cloakScaleFactor > skinScaleFactor;
129+
var extendedSkin = inputImage.Height / skinScaleFactor >= 64;
130+
124131
var croppedHead = inputImage.Clone(ctx =>
125-
ctx.Crop(new Rectangle(24 * scaleFactor, 8 * scaleFactor, 8 * scaleFactor, 8 * scaleFactor)));
132+
ctx.Crop(new Rectangle(24 * skinScaleFactor, 8 * skinScaleFactor, 8 * skinScaleFactor, 8 * skinScaleFactor)));
126133

127134
var croppedBody = inputImage.Clone(ctx =>
128-
ctx.Crop(new Rectangle(32 * scaleFactor, 20 * scaleFactor, 8 * scaleFactor, 12 * scaleFactor)));
129-
130-
var croppedLeftLeg = inputImage.Clone(ctx =>
131-
ctx.Crop(new Rectangle(12 * scaleFactor, 20 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)));
132-
133-
var croppedRightLeg = croppedLeftLeg.Clone(x => x.Flip(FlipMode.Horizontal));
134-
135-
var croppedLeftArm = inputImage.Clone(ctx =>
136-
ctx.Crop(new Rectangle(52 * scaleFactor, 20 * scaleFactor, 4 * scaleFactor, 12 * scaleFactor)));
137-
138-
var croppedRightArm = croppedLeftArm.Clone(x => x.Flip(FlipMode.Horizontal));
135+
ctx.Crop(new Rectangle(32 * skinScaleFactor, 20 * skinScaleFactor, 8 * skinScaleFactor, 12 * skinScaleFactor)));
136+
137+
var croppedRightLeg = inputImage.Clone(ctx =>
138+
ctx.Crop(new Rectangle(12 * skinScaleFactor, 20 * skinScaleFactor, 4 * skinScaleFactor, 12 * skinScaleFactor)));
139+
140+
var croppedRightArm = inputImage.Clone(ctx =>
141+
ctx.Crop(new Rectangle(52 * skinScaleFactor, 20 * skinScaleFactor, 4 * skinScaleFactor, 12 * skinScaleFactor)));
142+
143+
var croppedLeftLeg = extendedSkin
144+
? inputImage.Clone(ctx =>
145+
ctx.Crop(new Rectangle(28 * skinScaleFactor, 52 * skinScaleFactor, 4 * skinScaleFactor, 12 * skinScaleFactor)))
146+
: croppedRightLeg.Clone(x => x.Flip(FlipMode.Horizontal));
147+
148+
var croppedLeftArm = extendedSkin
149+
? inputImage.Clone(ctx =>
150+
ctx.Crop(new Rectangle(44 * skinScaleFactor, 52 * skinScaleFactor, 4 * skinScaleFactor, 12 * skinScaleFactor)))
151+
: croppedRightArm.Clone(x => x.Flip(FlipMode.Horizontal));
152+
153+
// var croppedRightArm = croppedLeftArm.Clone(x => x.Flip(FlipMode.Horizontal));
154+
155+
if (needSkinResizeToCloakSize)
156+
{
157+
croppedHead = ResizeImage(croppedHead, cloakScaleFactor);
158+
croppedBody = ResizeImage(croppedBody, cloakScaleFactor);
159+
croppedLeftLeg = ResizeImage(croppedLeftLeg, cloakScaleFactor);
160+
croppedRightLeg = ResizeImage(croppedRightLeg, cloakScaleFactor);
161+
croppedLeftArm = ResizeImage(croppedLeftArm, cloakScaleFactor);
162+
croppedRightArm = ResizeImage(croppedRightArm, cloakScaleFactor);
163+
}
139164

140165
Image croppedCloak = null;
141166

142167
if (includeCloak && cloakImage != null)
143168
croppedCloak = cloakImage.Clone(ctx =>
144-
ctx.Crop(new Rectangle(0, 0, 11, 17)))
169+
ctx.Crop(new Rectangle(0, 0, 11 * cloakScaleFactor, 17 * cloakScaleFactor)))
145170
.Clone(ctx => ctx.Resize(croppedBody.Width, croppedBody.Height, KnownResamplers.Box));
146171

147172
var newWidth = croppedLeftArm.Width * 2 + croppedBody.Width;
@@ -206,6 +231,13 @@ public static byte[] GetBack(UserTexture user, int size, bool includeCloak = fal
206231
return resizeMemoryStream.ToArray();
207232
}
208233

234+
private static Image ResizeImage(Image croppedHead, int cloakScaleFactor)
235+
{
236+
var newSize = croppedHead.Size;
237+
croppedHead = croppedHead.Clone(ctx => ctx.Resize(newSize.Width * cloakScaleFactor, newSize.Height * cloakScaleFactor, KnownResamplers.Box));
238+
return croppedHead;
239+
}
240+
209241

210242
private static MemoryStream ResizeImage(int size, Image inputImage, Image croppedImage)
211243
{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2+
USER $APP_UID
3+
WORKDIR /app
4+
EXPOSE 8080
5+
EXPOSE 8081
6+
7+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
8+
ARG BUILD_CONFIGURATION=Release
9+
WORKDIR /src
10+
COPY ["src/Gml.Web.Skin.Service/Gml.Web.Skin.Service.csproj", "src/Gml.Web.Skin.Service/"]
11+
RUN dotnet restore "src/Gml.Web.Skin.Service/Gml.Web.Skin.Service.csproj"
12+
COPY . .
13+
WORKDIR "/src/src/Gml.Web.Skin.Service"
14+
RUN dotnet build "Gml.Web.Skin.Service.csproj" -c $BUILD_CONFIGURATION -o /app/build
15+
16+
FROM build AS publish
17+
ARG BUILD_CONFIGURATION=Release
18+
RUN dotnet publish "Gml.Web.Skin.Service.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
19+
20+
FROM base AS final
21+
WORKDIR /app
22+
COPY --from=publish /app/publish .
23+
ENTRYPOINT ["dotnet", "Gml.Web.Skin.Service.dll"]

src/Gml.Web.Skin.Service/Gml.Web.Skin.Service.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
<Content Update="appsettings.Development.json">
2424
<DependentUpon>appsettings.json</DependentUpon>
2525
</Content>
26+
<Content Include="..\..\.dockerignore">
27+
<Link>.dockerignore</Link>
28+
</Content>
2629
</ItemGroup>
2730

2831

src/Gml.Web.Skin.Service/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"profiles": {
33
"http": {
44
"commandName": "Project",
5-
"launchBrowser": true,
5+
"launchBrowser": false,
66
"launchUrl": "swagger",
77
"environmentVariables": {
88
"ASPNETCORE_ENVIRONMENT": "Development"
-40.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)